C# Socket粘包处理讲解示例

所属分类: 软件编程 / C#教程 阅读数: 46
收藏 0 赞 0 分享

当socket接收到数据后,会根据buffer的大小一点一点的接收数据,比如:

对方发来了1M的数据量过来,但是,本地的buffer只有1024字节,那就代表socket需要重复很多次才能真正收完这逻辑上的一整个消息。
对方发来了5条2个字符的消息,本地的buffer(大小1024字节)会将这5条消息全部收入囊下...
那么,如何处理呢?下面我以最简单的一种文本消息来demo

根据上面所描述的情况,最重要的关键落在了下面3个因素的处理上

消息的结尾标记
接收消息时判断结尾标记
当本次buffer中没有结尾标记时怎么处理
我把写好的核心算法贴出来:

复制代码 代码如下:

StringBuilder sb = new StringBuilder();             //这个是用来保存:接收到了的,但是还没有结束的消息
        public void ReceiveMessage(object state)            //这个函数会被以线程方式运行
        {
            Socket socket = (Socket)state;
            while(true)
            {
                byte[] buffer = new byte[receiveBufferSize];  //buffer大小,此处为1024
                int receivedSize=socket.Receive(buffer);

                string rawMsg=System.Text.Encoding.Default.GetString(buffer, 0, receivedSize);
                int rnFixLength = terminateString.Length;   //这个是指消息结束符的长度,此处为\r\n
                for(int i=0;i<rawMsg.Length;)               //遍历接收到的整个buffer文本
                {
                    if (i <= rawMsg.Length - rnFixLength)
                    {
                        if (rawMsg.Substring(i, rnFixLength) != terminateString)//非消息结束符,则加入sb
                        {
                            sb.Append(rawMsg[i]);
                            i++;
                        }
                        else
                        {
                            this.OnNewMessageReceived(sb.ToString());//找到了消息结束符,触发消息接收完成事件
                            sb.Clear();
                            i += rnFixLength;
                        }  
                    }
                    else
                    {
                        sb.Append(rawMsg[i]);
                        i++;
                    }
                }
            }
        }

这个组件的使用方法:

复制代码 代码如下:

A2DTcpClient client = new A2DTcpClient("127.0.0.1", 5000);
            client.NewMessageReceived += new MessageReceived(client_NewMessageReceived);
            client.Connect();
            client.Send("HELLO");
            client.Close();

 

        static void client_NewMessageReceived(string msg)
        {
            Console.WriteLine(msg);
        }

更多精彩内容其他人还在看

C#中Datetimepicker出现问题的解决方法

这篇文章主要给大家介绍了关于C#中Datetimepicker出现问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

C# SQLite数据库入门使用说明

这篇文章主要给大家介绍了关于C#中SQLite数据库入门使用的相关资料,文中通过图文以及示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

C#实现批量下载图片到本地示例代码

这篇文章主要给大家介绍了关于C#如何实现批量下载图片到本地的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c#具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

如何获取C#中方法的执行时间以及其代码注入详解

这篇文章主要给大家介绍了关于如何获取C#中方法的执行时间以及其代码注入的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧
收藏 0 赞 0 分享

C#中通过LRU实现通用高效的超时连接探测

这篇文章主要介绍了c#中通过LRU实现通用高效的超时连接探测,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
收藏 0 赞 0 分享

如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

C#程序启动项的设置方法

这篇文章主要为大家详细介绍了C#程序启动项的设置方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

c#爬虫爬取京东的商品信息

这篇文章主要给大家介绍了关于利用c#爬虫爬取京东商品信息的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们随着小编来一起学习学习吧
收藏 0 赞 0 分享

C#随机数生成字母金字塔

这篇文章主要为大家详细介绍了C#随机数生成字母金字塔,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

WPF实现窗体中的悬浮按钮

这篇文章主要为大家详细介绍了WPF实现窗体中的悬浮按钮,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多