免费开源的Socket工具——SuperSocket的运用实例

免费开源的Socket工具——SuperSocket的运用实例


写这篇文章的初衷,是要解决TCP通讯的粘包和分包问题。本人所做的项目,遇见粘包和分包的问题比较严重。粘包的解决办法很多,比如使用struck定长,增加byte长度信息进行解析等等。但是,一方面这些方法和需求有冲突,另一方面按照网络上的做法,最后都不尽如人意。所以决定用第三方的工具SuperSocket,这里总结一下这个工具的使用经验。

本次demo地址: https://gitee.com/chenheze90/L14_SuperSocket

首先创建两个工程:SuperSocket的服务和客户端
在这里插入图片描述
给服务客户端导入SuperSocket插件
SuperSocket.Engine
这里要注意,是SuperSocket.Engine而不是SuperSocket!!!
在这里插入图片描述
在这里插入图片描述
服务器项目SuperSocketServer的主界面MainWindow增加Loaded="Window_Loaded"事件,load事件代码如下

private void Window_Loaded(object sender, RoutedEventArgs e)
{
     Task.Run(() =>
     {
     	 //实例化服务,AppServer是SuperSocket命名空间的tcp服务类
         AppServer appServer = new AppServer();
         appServer.NewSessionConnected += appServer_NewSessionConnected;
         appServer.NewRequestReceived += appServer_NewRequestReceived;
         appServer.SessionClosed += appServer_SessionClosed;
         
		 //配置:配置比较重要,特别是TextEncoding的设置,关系到是否能够传输汉字
         ServerConfig serverConfig = new ServerConfig()
         {
             Ip = "127.0.0.1",
             Port = 9514,
             TextEncoding = "UTF-8",
             Mode = SocketMode.Tcp,
         };
         
		 //安全起见,对服务的设置和启动做了防呆,可以有效避免异常的情况
         if (!appServer.Setup(serverConfig))
         {
             return;
         }
         if (!appServer.Start())
         {
             return;
         }
     });
 }

信息接收事件,必须要用Application.Current.Dispatcher.Invoke,因为控件是前端线程生成,其他线程不能直接使用

private void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
{
    try
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            txbMsg.Text += requestInfo.Key;
        });                
    }
    catch (Exception ex)
    {
        log4net.LogManager.GetLogger("TCP").Warn("接受数据失败", ex);
    }
}

客户端连接事件和会话关闭事件:客户端连接事件在处理高并发和客户端管理的情况下比较有用,可以有选择地释放部分无用的客户端,节省内存和消耗。
会话关闭事件:supersocket有一个问题尚未解决,当发送的信息量超过1448byte的时候,会触发session关闭事件。因为tcp的数据上限是1448byte。

static void appServer_NewSessionConnected(AppSession session)
{

}

static void appServer_SessionClosed(AppSession session, CloseReason reason)
{
    log4net.LogManager.GetLogger("TCP").Warn("TCP客户端断连,原因:" + reason.ToString());
}

客户端代码相对简单,就是将文本转化成byte[]就可以发送。
但是SuperSocket有个特殊的地方,一定要加上"\r\n"。如下代码所示,需要将"\r\n"转化成byte[]之后,加在原字符串的末尾才可以发送。

private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            TcpClient tcpClient = new TcpClient();
            tcpClient.Connect("127.0.0.1", 9514);
            NetworkStream netStream = tcpClient.GetStream();
            while (true)
            {
                try
                {

                    string tcpdata = "你好,世界!";
                    byte[] byteArray = Encoding.UTF8.GetBytes(tcpdata);
                    byte[] byteArrayLength = Encoding.UTF8.GetBytes("\r\n");//\r\n

                    byte[] combined = new byte[byteArray.Length + 2];
                    byteArray.CopyTo(combined, 0);
                    byteArrayLength.CopyTo(combined, byteArray.Length);

                    netStream.Write(combined, 0, combined.Length);
                    //rb.IsChecked = false;
                }
                catch (Exception ex)
                {
                    netStream.Close();
                    tcpClient.Close();
                    MessageBox.Show(ex.ToString());
                }
                await Task.Delay(5000);
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值