事件驱动的TCP协议Socket通信

事件驱动的TCP协议Socket通信

介绍

常规的Socket通信案例一般都是在某个线程中建立连接,然后用一个while(true)循环判断是或否有数据传输,但是这种方法有局限性。

1、收到消息在处理过程中无法接受新消息

2、线程容易堵塞

3、需要客户端服务端双发进行心跳响应

事件驱动的方式可以有效的提高Socket通信效率,让在一端有操作的同时,可以触发另一端的事件。

类似工具库:Cowboy.Socket、FastSocket

使用方法

1、打开VS,在Nuget里搜索SuperSocket

2、安装SuperSocket.Client和SuperSocket

image-20200228133141918

3、服务端监听端口以及注册事件

AppServer appServer;
appServer = new AppServer();
            if (!appServer.Setup(int.Parse(txt_port.Text)))
            {
                SetMessage("Failed to Setup");
                return;
            }
            if (!appServer.Start())
            {
                SetMessage("Failed to Start");
                return;
            }
            else
            {
                SetMessage("开启监听");
            }
            //SuperSocket自定义了三个事件 ,连接事件,接收事件,关闭事件
            appServer.NewSessionConnected += appServer_NewSessionConnected;
            appServer.NewRequestReceived += appServer_NewRequestReceived;
            appServer.SessionClosed += appServer_SessionClosed;

4、服务端事件

void appServer_NewSessionConnected(AppSession session)
        {
            //有新连接的时候,添加记录  session.LocalEndPoint属性获取当前session的ip和端口号
            //AppSession 代表一个和客户端的逻辑连接,基于连接的操作应该定于在该类之中。你可以用该类的实例发送数据到客户端,接收客户端发送的数据或者关闭连接。

            //获取远程客户端的ip端口号
            ipAddress_Connect = session.RemoteEndPoint.ToString();
            ComboboxHandle(ipAddress_Connect, OperateType.Add);
            sessionList.Add(ipAddress_Connect, session);
            SetMessage(ipAddress_Connect + "已连接!");
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="session"></param>
        /// <param name="requestInfo"></param>
        void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
        {
            //requestInfo.Key 是请求的命令行用空格分隔开的第一部分
            //requestInfo.Parameters 是用空格分隔开的其余部分
            //requestInfo.Body 是出了请求头之外的所有内容
            
            ipAddress_Receive = session.RemoteEndPoint.ToString();
            SetMessage("收到" + ipAddress_Receive + "数据: "+requestInfo.Key +" "+ requestInfo.Body);
        }

        /// <summary>
        /// 关闭连接
        /// </summary>
        /// <param name="session"></param>
        /// <param name="value"></param>
        void appServer_SessionClosed(AppSession session, SocketBase.CloseReason value)
        {   
            ipAddress_Close = session.RemoteEndPoint.ToString();
            ComboboxHandle(ipAddress_Close, OperateType.Remove);
            sessionList.Remove(ipAddress_Close);
            SetMessage(ipAddress_Close + "已关闭连接!");
        }

5、客户端建立连接以及注册事件

SuperSocket.ClientEngine.AsyncTcpSession async=new AsyncTcpSession();
async.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
async.Connected += client_Connected;
            // 发生错误的处理
            async.Error += client_Error;
            // 收到服务器数据事件
            async.DataReceived += client_DataReceived;
            async.Closed += client_Closed;

6、客户端事件

        void client_Error(object sender, ErrorEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
        }

        void client_Connected(object sender, EventArgs e)
        {
            Console.WriteLine("连接成功");
        }

        void client_DataReceived(object sender, DataEventArgs e)
        {
            string msg = Encoding.Default.GetString(e.Data);
            MessageBox.Show(msg.ToString());
            Console.WriteLine(msg);
        }

        void client_Closed(object sender, EventArgs e)
        {
            Console.WriteLine("连接断开");
        }

7、客户端/服务端发送消息

Client:
string message = "123";
            byte[] data = Encoding.Default.GetBytes(message);
            
            async.Send(data,0,data.Length);

8、其他

服务端接受消息必须要有回车加换行符:\r\n

源码地址

码云地址:https://gitee.com/PErobin/Socket.git

SVN地址:svn://gitee.com/PErobin/Socket

猜你喜欢

转载自www.cnblogs.com/aqyl/p/12376925.html