Skip to content

Socket粘包

L edited this page May 6, 2020 · 2 revisions

Socket粘包一般分为两种:
1、Socket发送方:Socket发送消息时会将消息存放在一个缓冲区里,等待缓冲区满或者等待时间已到则发送出去。
2、Socket接收方:接收方一般是因为没有及时从Socket缓冲区里取数据导致后来数据累加到一起才获取导致。

解决思路

1.延迟发送
2.NoDelay=true
NoDelay是否正在使用 Nagle 算法,这是socket提供的一个方法,我试了单独使用感觉效果不大
Socket.NoDelay 属性

socket.NoDelay = true;

3.不管你发送的是多少,即使是1个字节,也将它放到一个1024的buffer中,保证每次发送的都是1024个长度,与服务端保持一致,这样也可以,就是有点浪费网络资源,高并发的情况下,不提倡

internal async Task AsyncSend(Socket socket, byte[] data)
{
    //开始发送消息
    //解决粘包的问题
    byte[] newData = new byte[1024];
    for (int i = 0; i < data.Length; i++)
    {
        newData[i] = data[i];
    }
    socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
    {
        try
        {
            //完成消息发送
            int length = socket.EndSend(asyncResult);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }, null);
}

4.分包方法 即发送消息的头4个字节加上消息长度,接受方接收到数据后先解析长度然后根据消息长度来获取消息。每次接收数据有个总长度 在总长度里循环遍历消息即可。

参考资料

解决Socket粘包问题——C#代码
C# Socket粘包

Clone this wiki locally