这是一个SuperSocket 简单示例,包括服务端和客户端。
一、首先使用NuGet安装SuperSocket和SuperSocket.Engine
二、实现IRequestInfo(数据包):
数据包格式:
包头4个字节,前2个字节是请求命令,后2个字节是正文长度
using@H_404_25@ SuperSocket.socketBase.Protocol;@H_404_25@ System;@H_404_25@ System.Collections.Generic;@H_404_25@ System.linq;@H_404_25@ System.Text;@H_404_25@ System.Threading.Tasks;@H_404_25@namespace@H_404_25@ SuperSocketServer{ @H_404_25@public@H_404_25@ class@H_404_25@ MyRequestInfo : IRequestInfo { @H_404_25@public@H_404_25@ MyRequestInfo(byte@H_404_25@[] header,byte@H_404_25@[] bodyBuffer) { Key @H_404_25@= ASCIIEnCoding.ASCII.GetString(new@H_404_25@ byte@H_404_25@[] { header[0@H_404_25@],header[1@H_404_25@] }); Data @H_404_25@= bodyBuffer; } @H_404_25@string@H_404_25@ Key { get@H_404_25@; set@H_404_25@; } @H_404_25@byte@H_404_25@[] Data { string@H_404_25@ Body { @H_404_25@get@H_404_25@ { @H_404_25@return@H_404_25@ EnCoding.UTF8.GetString(Data); } } }}@H_404_25@
VIEw Code@H_404_25@三、实现FixedheaderReceiveFilter(数据包解析):
SuperSocket.Facility.Protocol;@H_404_25@class@H_404_25@ MyReceiveFilter : FixedheaderReceiveFilter<MyRequestInfo> { @H_404_25@public@H_404_25@ MyReceiveFilter() : base@H_404_25@(4@H_404_25@) { } @H_404_25@protected@H_404_25@ overrIDe@H_404_25@ int@H_404_25@ GetbodyLengthFromheader(int@H_404_25@ offset,1)">int@H_404_25@ length) { @H_404_25@return@H_404_25@ BitConverter.ToInt16(byte@H_404_25@[] { header[offset + 2@H_404_25@],header[offset + 3@H_404_25@] },0@H_404_25@); } @H_404_25@overrIDe@H_404_25@ MyRequestInfo ResolveRequestInfo(ArraySegment<byte@H_404_25@> header,1)">byte@H_404_25@[] bodyBuffer,1)">byte@H_404_25@[] body = bodyBuffer.Skip(offset).Take(length).ToArray(); @H_404_25@return@H_404_25@ new@H_404_25@ MyRequestInfo(header.Array,body); } }}@H_404_25@
VIEw Code@H_404_25@四、实现AppSession:
SuperSocket.socketBase;@H_404_25@class@H_404_25@ MySession : AppSession<MySession,MyRequestInfo>public@H_404_25@ MySession() { } @H_404_25@voID@H_404_25@ OnSessionStarted() { } @H_404_25@ OnInit() { @H_404_25@base@H_404_25@.OnInit(); } @H_404_25@ HandleUnkNownRequest(MyRequestInfo requestInfo) { } @H_404_25@ HandleException(Exception e) { } @H_404_25@ OnSessionClosed(CloseReason reason) { @H_404_25@.OnSessionClosed(reason); } }}@H_404_25@
VIEw Code@H_404_25@五、实现AppServer:
SuperSocket.socketBase.Config;@H_404_25@ System.Threading.Tasks;@H_404_25@ Utils;@H_404_25@class@H_404_25@ MyServer : AppServer<MySession,1)">public@H_404_25@ MyServer() : base@H_404_25@(new@H_404_25@ DefaultReceiveFilterFactory<MyReceiveFilter,1)">()) { @H_404_25@this@H_404_25@.NewSessionConnected += MyServer_NewSessionConnected; @H_404_25@this@H_404_25@.SessionClosed += MyServer_SessionClosed; } @H_404_25@bool@H_404_25@ Setup(IRootConfig rootConfig,IServerConfig config) { @H_404_25@.Setup(rootConfig,config); } @H_404_25@ OnStarted() { @H_404_25@.OnStarted(); } @H_404_25@ OnStopped() { @H_404_25@.OnStopped(); } @H_404_25@ MyServer_NewSessionConnected(MySession session) { LogHelper.Log(@H_404_25@"@H_404_25@新客户端连接,SessionID=@H_404_25@"@H_404_25@ + session.SessionID.Substring(session.SessionID.Length - 6@H_404_25@).toupper()); } @H_404_25@ MyServer_SessionClosed(MySession session,CloseReason value) { LogHelper.Log(@H_404_25@客户端失去连接,SessionID=@H_404_25@6@H_404_25@).toupper() + ,原因:@H_404_25@"@H_404_25@ + value); } }}@H_404_25@
VIEw Code@H_404_25@六、实现CommandBase<MySession,MyRequestInfo>:
SuperSocket.socketBase.Command;@H_404_25@class@H_404_25@ EC : CommandBase<MySession,1)"> ExecuteCommand(MySession session,MyRequestInfo requestInfo) { LogHelper.Log(@H_404_25@客户端 @H_404_25@ 发来消息:@H_404_25@ requestInfo.Body); @H_404_25@byte@H_404_25@[] bytes = ASCIIEnCoding.UTF8.GetBytes(消息收到@H_404_25@"@H_404_25@); session.Send(bytes,@H_404_25@,bytes.Length); } }}@H_404_25@
VIEw Code@H_404_25@七、服务端Form1.cs代码:
System.ComponentModel;@H_404_25@ System.Data;@H_404_25@ System.Drawing;@H_404_25@ System.windows.Forms;@H_404_25@partial@H_404_25@ Form1 : Form { @H_404_25@private@H_404_25@ MyServer _myServer; @H_404_25@ Form1() { InitializeComponent(); LogHelper.Init(@H_404_25@this@H_404_25@private@H_404_25@ voID@H_404_25@ Form1_Load(object@H_404_25@ sender,EventArgs e) { _myServer @H_404_25@= MyServer(); ServerConfig serverConfig @H_404_25@= ServerConfig() { Port @H_404_25@= 2021@H_404_25@ }; _myServer.Setup(serverConfig); _myServer.Start(); } @H_404_25@voID@H_404_25@ button1_Click(foreach@H_404_25@ (MySession session in@H_404_25@ _myServer.GetAllSessions()) { @H_404_25@服务端广播消息@H_404_25@); session.Send(bytes,bytes.Length); } } }}@H_404_25@
VIEw Code@H_404_25@八、客户端Form1.cs代码:
System.IO;@H_404_25@ System.Net;@H_404_25@ System.Net.sockets;@H_404_25@ System.windows.Forms;@H_404_25@ SuperSocketClIEnt{ @H_404_25@ Socket _socket; @H_404_25@ NetworkStream _socketStream; @H_404_25@ Form1() { InitializeComponent(); } @H_404_25@new@H_404_25@ IPEndPoint(IPAddress.Parse(127.0.0.1@H_404_25@"@H_404_25@),1)">); _socket @H_404_25@= Socket(serverAddress.AddressFamily,SocketType.Stream,ProtocolType.Tcp); _socket.Connect(serverAddress); _socketStream @H_404_25@= NetworkStream(_socket); @H_404_25@//@H_404_25@socketasynceventargs socketAsyncArgs = new socketasynceventargs(); @H_404_25@byte[] buffer = new byte[10240]; @H_404_25@socketAsyncArgs.SetBuffer(buffer,buffer.Length); @H_404_25@socketAsyncArgs.Completed += ReciveAsync; @H_404_25@_socket.ReceiveAsync(socketAsyncArgs);@H_404_25@ Receive(_socket); } @H_404_25@ { Random rnd @H_404_25@= Random(); @H_404_25@string@H_404_25@ cmd = EC@H_404_25@; @H_404_25@string@H_404_25@ msg = 测试消息00@H_404_25@"@H_404_25@ + rnd.Next(0@H_404_25@,1)">100@H_404_25@).ToString(00@H_404_25@); Send(cmd,msg); }); } @H_404_25@voID@H_404_25@ Send(string@H_404_25@ cmd,1)"> msg) { @H_404_25@byte@H_404_25@[] cmdBytes = EnCoding.ASCII.GetBytes(cmd); @H_404_25@byte@H_404_25@[] msgBytes = EnCoding.UTF8.GetBytes(msg); @H_404_25@byte@H_404_25@[] lengthBytes = BitConverter.GetBytes((short@H_404_25@)msgBytes.Length); _socketStream.Write(cmdBytes,cmdBytes.Length); _socketStream.Write(lengthBytes,lengthBytes.Length); _socketStream.Write(msgBytes,msgBytes.Length); _socketStream.Flush(); Log(@H_404_25@发送:@H_404_25@ msg); } @H_404_25@voID@H_404_25@ ReciveAsync( obj,socketasynceventargs e) { @H_404_25@if@H_404_25@ (e.BytesTransferred > ) { @H_404_25@string@H_404_25@ data = ASCIIEnCoding.UTF8.GetString(e.Buffer,e.BytesTransferred); Log(@H_404_25@接收:@H_404_25@ data); } } @H_404_25@ Receive(Socket socket) { Task.Factory.StartNew(() @H_404_25@=>try@H_404_25@ { @H_404_25@while@H_404_25@ (true@H_404_25@) { @H_404_25@byte@H_404_25@[] buffer = byte@H_404_25@[10240@H_404_25@]; @H_404_25@int@H_404_25@ receiveCount = _socket.Receive(buffer,buffer.Length,SocketFlags.None); @H_404_25@if@H_404_25@ (receiveCount > ) { @H_404_25@string@H_404_25@ data = ASCIIEnCoding.UTF8.GetString(buffer,receiveCount); Log(@H_404_25@ data); } } } @H_404_25@catch@H_404_25@ (Exception ex) { Log(@H_404_25@Receive出错:@H_404_25@"@H_404_25@ + ex.Message + \r\n@H_404_25@ ex.StackTrace); } },TaskCreationoptions.LongRunning); } @H_404_25@#region@H_404_25@ Log ///@H_404_25@ <summary>@H_404_25@ ///@H_404_25@ 输出日志 @H_404_25@</summary>@H_404_25@ voID@H_404_25@ Log( log) { @H_404_25@if@H_404_25@ (!.Isdisposed) { @H_404_25@this@H_404_25@.BeginInvoke(new@H_404_25@ Action(() => { txtLog.AppendText(DateTime.Now.ToString(@H_404_25@HH:mm:ss.fff@H_404_25@"@H_404_25@) + "@H_404_25@ "@H_404_25@ + log + \r\n\r\n@H_404_25@); })); } } @H_404_25@#endregion@H_404_25@ }}@H_404_25@
VIEw Code@H_404_25@辅助工具类LogHelper:
SuperSocketServer;@H_404_25@ Utils{ @H_404_25@ LogHelper { @H_404_25@static@H_404_25@ Form1 _frm; @H_404_25@ TextBox _txtLog; @H_404_25@static@H_404_25@ Init(Form1 frm,TextBox txt) { _frm @H_404_25@= frm; _txtLog @H_404_25@= txt; } @H_404_25@_frm.Isdisposed) { _frm.BeginInvoke(@H_404_25@ { _txtLog.AppendText(DateTime.Now.ToString(@H_404_25@); })); } } }}@H_404_25@
VIEw Code@H_404_25@测试截图:
问题:
1、客户端使用socketasynceventargs异步接收数据,第一次能收到数据,后面就收不到了,不知道什么原因,同步接收数据没问题
2、SuperSocket源码中的示例和网上相关的博客,客户端要么是原生Socket实现,要么是Socket调试工具,客户端不需要复杂一点的功能或数据结构吗?客户端不需要解包吗?SuperSocket不能用来写客户端吗?
总结
以上是内存溢出为你收集整理的SuperSocket 简单示例全部内容,希望文章能够帮你解决SuperSocket 简单示例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)