本文記錄使用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版代碼下載


