SuperSocket 简单示例

  • A+
所属分类:.NET技术
摘要

这是一个SuperSocket 简单示例,包括服务端和客户端。一、首先使用NuGet安装SuperSocket和SuperSocket.Engine

这是一个SuperSocket 简单示例,包括服务端和客户端。

一、首先使用NuGet安装SuperSocket和SuperSocket.Engine

SuperSocket 简单示例

二、实现IRequestInfo(数据包):

数据包格式:

包头4个字节,前2个字节是请求命令,后2个字节是正文长度

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocket.SocketBase.Protocol; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace SuperSocketServer {     public class MyRequestInfo : IRequestInfo     {         public MyRequestInfo(byte[] header, byte[] bodyBuffer)         {             Key = ASCIIEncoding.ASCII.GetString(new byte[] { header[0], header[1] });             Data = bodyBuffer;         }          public string Key { get; set; }          public byte[] Data { get; set; }          public string Body         {             get             {                 return Encoding.UTF8.GetString(Data);             }         }     } }

View Code

三、实现FixedHeaderReceiveFilter(数据包解析):

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocket.Facility.Protocol; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace SuperSocketServer {     public class MyReceiveFilter : FixedHeaderReceiveFilter<MyRequestInfo>     {         public MyReceiveFilter() : base(4)         {          }          protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)         {             return BitConverter.ToInt16(new byte[] { header[offset + 2], header[offset + 3] }, 0);         }          protected override MyRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)         {             byte[] body = bodyBuffer.Skip(offset).Take(length).ToArray();             return new MyRequestInfo(header.Array, body);         }     } }

View Code

四、实现AppSession:

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocket.SocketBase; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace SuperSocketServer {     public class MySession : AppSession<MySession, MyRequestInfo>     {         public MySession()         {          }          protected override void OnSessionStarted()         {          }          protected override void OnInit()         {             base.OnInit();         }          protected override void HandleUnknownRequest(MyRequestInfo requestInfo)         {          }          protected override void HandleException(Exception e)         {          }          protected override void OnSessionClosed(CloseReason reason)         {             base.OnSessionClosed(reason);         }     } }

View Code

五、实现MyServer:

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Protocol; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Utils;  namespace SuperSocketServer {     public class MyServer : AppServer<MySession, MyRequestInfo>     {         public MyServer() : base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>())         {             this.NewSessionConnected += MyServer_NewSessionConnected;             this.SessionClosed += MyServer_SessionClosed;         }          protected override bool Setup(IRootConfig rootConfig, IServerConfig config)         {             return base.Setup(rootConfig, config);         }          protected override void OnStarted()         {             base.OnStarted();         }          protected override void OnStopped()         {             base.OnStopped();         }          void MyServer_NewSessionConnected(MySession session)         {             LogHelper.Log("新客户端连接,SessionID=" + session.SessionID.Substring(session.SessionID.Length - 6).ToUpper());         }          void MyServer_SessionClosed(MySession session, CloseReason value)         {             LogHelper.Log("客户端失去连接,SessionID=" + session.SessionID.Substring(session.SessionID.Length - 6).ToUpper() + ",原因:" + value);         }     } }

View Code

六、服务端Form1.cs代码:

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocket.SocketBase.Config; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Utils;  namespace SuperSocketServer {     public partial class Form1 : Form     {         private MyServer _myServer;          public Form1()         {             InitializeComponent();             LogHelper.Init(this, txtLog);         }          private void Form1_Load(object sender, EventArgs e)         {             _myServer = new MyServer();             ServerConfig serverConfig = new ServerConfig()             {                 Port = 2021             };             _myServer.Setup(serverConfig);             _myServer.Start();         }          private void button1_Click(object sender, EventArgs e)         {             foreach (MySession session in _myServer.GetAllSessions())             {                 byte[] bytes = ASCIIEncoding.UTF8.GetBytes("服务端广播消息");                 session.Send(bytes, 0, bytes.Length);             }         }     } }

View Code

七、客户端Form1.cs代码:

SuperSocket 简单示例SuperSocket 简单示例

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;  namespace SuperSocketClient {     public partial class Form1 : Form     {         private Socket _socket;          private NetworkStream _socketStream;          public Form1()         {             InitializeComponent();         }          private void Form1_Load(object sender, EventArgs e)         {             EndPoint serverAddress = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2021);             _socket = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);             _socket.Connect(serverAddress);             _socketStream = new NetworkStream(_socket);              //SocketAsyncEventArgs socketAsyncArgs = new SocketAsyncEventArgs();             //byte[] buffer = new byte[10240];             //socketAsyncArgs.SetBuffer(buffer, 0, buffer.Length);             //socketAsyncArgs.Completed += ReciveAsync;             //_socket.ReceiveAsync(socketAsyncArgs);              Receive(_socket);          }          private void button1_Click(object sender, EventArgs e)         {             Task.Run(() =>             {                 Random rnd = new Random();                 string cmd = "EC";                 string msg = "测试消息00" + rnd.Next(0, 100).ToString("00");                 Send(cmd, msg);             });         }          public void Send(string cmd, string msg)         {             byte[] cmdBytes = Encoding.ASCII.GetBytes(cmd);             byte[] msgBytes = Encoding.UTF8.GetBytes(msg);             byte[] lengthBytes = BitConverter.GetBytes((short)msgBytes.Length);              _socketStream.Write(cmdBytes, 0, cmdBytes.Length);             _socketStream.Write(lengthBytes, 0, lengthBytes.Length);             _socketStream.Write(msgBytes, 0, msgBytes.Length);             _socketStream.Flush();             Log("发送:" + msg);         }          private void ReciveAsync(object obj, SocketAsyncEventArgs e)         {             if (e.BytesTransferred > 0)             {                 string data = ASCIIEncoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);                 Log("接收:" + data);             }         }          private void Receive(Socket socket)         {             Task.Factory.StartNew(() =>             {                 try                 {                     while (true)                     {                         byte[] buffer = new byte[10240];                         int receiveCount = _socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);                         if (receiveCount > 0)                         {                             string data = ASCIIEncoding.UTF8.GetString(buffer, 0, receiveCount);                             Log("接收:" + data);                         }                     }                 }                 catch (Exception ex)                 {                     Log("Receive出错:" + ex.Message + "rn" + ex.StackTrace);                 }             }, TaskCreationOptions.LongRunning);         }          #region Log         /// <summary>         /// 输出日志         /// </summary>         private void Log(string log)         {             if (!this.IsDisposed)             {                 this.BeginInvoke(new Action(() =>                 {                     txtLog.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + log + "rnrn");                 }));             }         }         #endregion      } }

View Code

辅助工具类LogHelper:

SuperSocket 简单示例SuperSocket 简单示例

using SuperSocketServer; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;  namespace Utils {     public class LogHelper     {         private static Form1 _frm;          private static TextBox _txtLog;          public static void Init(Form1 frm, TextBox txt)         {             _frm = frm;             _txtLog = txt;         }          /// <summary>         /// 输出日志         /// </summary>         public static void Log(string log)         {             if (!_frm.IsDisposed)             {                 _frm.BeginInvoke(new Action(() =>                 {                     _txtLog.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + log + "rnrn");                 }));             }         }      } }

View Code

测试截图:

SuperSocket 简单示例

问题:

1、客户端使用SocketAsyncEventArgs异步接收数据,第一次能收到数据,后面就收不到了,不知道什么原因,同步接收数据没问题

2、SuperSocket源码中的示例和网上相关的博客,客户端要么是原生Socket实现,要么是Socket调试工具,客户端不需要复杂一点的功能或数据结构吗?客户端不需要解包吗?SuperSocket不能用来写客户端吗?