• 事件驱动的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、其他

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

    源码地址

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

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

  • 相关阅读:
    django ---解决跨域的问题
    python-isinstance函数
    python每日一学-os模块常用函数
    调用父类方法super
    fiddler小运用-断点
    劝告
    Django model字段
    Jenkins自动化部署前端
    解决react使用antd table组件固定表头后,表头和表体列不对齐以及配置fixed固定左右侧后行高度不对齐
    高德地图判断点的位置是否在浏览器可视区域内
  • 原文地址:https://www.cnblogs.com/aqyl/p/12376925.html
Copyright © 2020-2023  润新知