zoukankan      html  css  js  c++  java
  • C# Socket的粘包处理(转)

    http://www.cnblogs.com/aarond/p/Socket111.html

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

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

    那么,如何处理呢?下面我以最简单的一种文本消息来demo

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

    1. 消息的结尾标记
    2. 接收消息时判断结尾标记
    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;   //这个是指消息结束符的长度,此处为
    
                    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);
            }
    复制代码

     组件代码下载

  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/bluestorm/p/3521359.html
Copyright © 2011-2022 走看看