本文记录使用SuperSocket搭建Socket服务端,然后搭建客户端与之通信
环境:.Net 4.5
一、先说服务端
创建一个控制台SuperSocketServer,创建会话类:MyServerSession
public class MyServerSession:AppSession<MyServerSession>
{
public override void Send(string message)
{
Console.WriteLine("发送消息:"+message);
base.Send(message);
}
protected override void OnSessionStarted()
{
Console.WriteLine("Session已启动" );
base.OnSessionStarted();
}
protected override void OnInit()
{
this.Charset = Encoding.GetEncoding("gb2312");
base.OnInit();
}
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
Console.WriteLine("未知请求");
base.HandleUnknownRequest(requestInfo);
}
}
分别表示4个状态和动作,一看就明白。
然后创建服务类:MyServer
public class MyServer:AppServer<MyServerSession>
{
protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
{
Console.WriteLine("正在准备配置文件");
return base.Setup(rootConfig, config);
}
protected override void OnStarted()
{
Console.WriteLine("服务已启动");
base.OnStarted();
}
protected override void OnStopped()
{
Console.WriteLine("服务已停止");
base.OnStopped();
}
protected override void OnNewSessionConnected(MyServerSession session)
{
Console.WriteLine("新链接进入:" + session.LocalEndPoint.Address.ToString() +":"+ session.RemoteEndPoint.Port + "(" + session.SessionID + ")" + ",时间:" + DateTime.Now);
base.OnNewSessionConnected(session);
}
protected override void OnSessionClosed(MyServerSession session, CloseReason reason)
{
Console.WriteLine("链接关闭:" + session.LocalEndPoint.Address.ToString() + ":" + session.RemoteEndPoint.Port + "(" + session.SessionID + ")" + ",时间:" + DateTime.Now);
base.OnSessionClosed(session, reason);
}
}
表示服务器的4个状态,这些状态可以根据业务进行扩展
再创建命令类:ECHO执行客户端的命令
public class ECHO: CommandBase<MyServerSession, StringRequestInfo>
{
public override void ExecuteCommand(MyServerSession session, StringRequestInfo requestInfo)
{
if (requestInfo.Parameters.Length < 2)
return;
string cmd = requestInfo.Parameters[0];
switch (cmd)
{
case "heart":// heart 2
session.Send("ok");
break;
case "hello":// hello 2
session.Send("你说:"+ requestInfo.Parameters[1]);
break;
case "login":// login 我 000 000
string userID = requestInfo.Parameters[1];
Console.WriteLine(userID + "登录成功");
break;
case "sendto"://sendto 我ID 他ID 内容
rev.Send(requestInfo.Parameters[3]);
Console.WriteLine(string.Format("{0}对{1}说:{2}", requestInfo.Parameters[1],requestInfo.Parameters[2], requestInfo.Parameters[3]));
break;
default:
break;
}
if (requestInfo.Parameters[0] == "all")
{
var sessions = session.AppServer.GetAllSessions();
foreach (var item in sessions)
{
item.Send(requestInfo.Body);
}
}
//根据参数个数或者其他条件判断,来进行一些自己的操作
//if (requestInfo.Parameters.Length == 2)
//{
// Console.WriteLine("调用成功");
// session.Send(string.Format("{0}:{1},已经成功接收到你的请求\r\n", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port));
//}
//else
//{
// session.Send("参数不正确\r\n");
//}
//session.Send(requestInfo.Body);
}
}
这个类里面列举了执行动作判断,消息群发,一对一发,当然叶可以一对多
最后是启动服务main
static void Main(string[] args)
{
IBootstrap bootstrap = BootstrapFactory.CreateBootstrap();
if (!bootstrap.Initialize())
{
Console.WriteLine(DateTime.Now + ":Socket初始化失败\r\n");
return;
}
var result = bootstrap.Start();
foreach (var server in bootstrap.AppServers)
{
if (server.State == ServerState.Running)
{
Console.WriteLine(DateTime.Now + ":serverName为:" + server.Name + "Socket运行中\r\n");
Console.Read();
}
else
{
Console.WriteLine(DateTime.Now + ":serverName为:" + server.Name + "Socket启动失败\r\n");
}
}
}
也是一看就能明白,还有配置文件:
<configuration>
<configSections>
<!--log 日志记录-->
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
<!--SocketEngine-->
<section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
</configSections>
<!--配置SocketServer路径-->
<superSocket>
<servers>
<server name="MySocket" textEncoding="gb2312"
serverType="SuperSocketServer.MyServer, SuperSocketServer"
ip="Any" port="2018" maxConnectionNumber="100">
</server>
</servers>
</superSocket>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
全部的引用是这几个:
二、再说客户端
目前代码较为简单,实现了心跳与断线重连
class Program
{
private static AsyncTcpSession client;
static System.Timers.Timer timer = null;
private int port = 2018;
static void Main(string[] args)
{
new Program().Link();
string input = Console.ReadLine();
while (input != "exit"&& !string.IsNullOrEmpty(input))
{
if (client != null && client.IsConnected)
{
var msg = System.Text.Encoding.Default.GetBytes("echo hello " + input + "\r\n");
client.Send(msg,0, msg.Length);
input = Console.ReadLine();
}
}
}
private void Link()
{
client = new AsyncTcpSession();
client.Connected += OnClientConnected;
client.Error += OnClientError;
client.Closed += OnClientClosed;
// 收到服务器数据事件
client.DataReceived += client_DataReceived;
//每10s发送一次心跳或尝试一次重连
timer = new System.Timers.Timer(10000);
timer.Elapsed += new System.Timers.ElapsedEventHandler((s, x) =>
{
//心跳包
if (client.IsConnected)
{
var heartMsg = System.Text.Encoding.Default.GetBytes("echo heart 2\r\n");
client.Send(heartMsg,0, heartMsg.Length);
}
//断线重连
else if (!client.IsConnected)
{
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), port));
}
});
timer.Enabled = true;
timer.Start();
}
private void OnClientConnected(object sender, EventArgs e)
{
Console.WriteLine("已连接" + '\n');
}
private void OnClientClosed(object sender, EventArgs e)
{
Console.WriteLine("已断开" + '\n');
}
private void OnClientError(object sender, ErrorEventArgs e)
{
Console.WriteLine($"错误:{e.Exception.Message}" + '\n');
}
void client_DataReceived(object sender, DataEventArgs e)
{
string msg = Encoding.Default.GetString(e.Data);
Console.WriteLine(msg.Trim('\0'));
}
}
引用如下:
控制台版代码下载,压缩包里面带了tcptool可以不用客户端测试,记得每个命令完了要敲回车
Winform版代码下载

