套接字行为-数据无序写入

本文关键字:无序 数据 套接字 | 更新日期: 2023-09-27 18:17:59

我有一个接口,其中线程写入套接字并被远程服务器接收。当线程争用变得很高时,就会出现套接字数据乱序的问题。我有一个通过套接字发送的"标准"消息,并且我可以在字节级别上看到第二个逻辑消息正在写入第一个逻辑消息的中途。显然,这意味着接口失败,因为数据已损坏。

在套接字上使用的唯一特殊设置是

m_socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Tcp,
System.Net.Sockets.SocketOptionName.NoDelay, 1)
m_Socket.Connect(m_remoteServerName, m_remoteServerPort)
我尝试了一个简单的解决方案,在我的逻辑消息周围加一个锁,所以我的逻辑是:
lock (sending)
{
    msgbytes = GetLogicalMessage();
    m_socket.Send(msgbytes, 0, msgbytes.Length, SocketFlags.None);
}

接收方实际上正在做相反的事情,从每个逻辑消息中读取消息头和消息负载。

发送方法正在从多个线程访问,但我被困在哪里看。我已经通过代码和所有访问套接字是通过锁定的方法(除了接收)。除了. send()没有按照我期望的方式工作之外,我看不到任何明显的东西。根据我的理解,这是一个流,因此缓冲区写入将需要完成,即使在调用结束时数据没有推出套接字。

套接字行为-数据无序写入

是的,你对Send方法的理解是不正确的——它不能保证你给它的所有字节都被放入套接字发送缓冲区中。缓冲区可能没有足够的空间,所以您必须注意返回值,这是被复制的字节数。

编辑0:

通常的方法是绕send循环。请注意,内核内TCP/IP堆栈会异步地消耗缓冲区,所以下一次对send的调用不一定会再次阻塞。

但是,在线程存在的情况下,这并不太好,因为您将在发送消息时获得任意延迟。

我可能会建议将套接字处理移动到它自己的线程中,并通过队列将工作连接到它,这将适应消息传递中的峰值。