【发布时间】:2015-10-15 23:00:39
【问题描述】:
我有一个接口,线程写入套接字并由远程服务器接收。当线程争用变高时,会出现套接字数据乱序的问题。我有一条通过套接字发送的“标准”消息,我可以在字节级别看到第二条逻辑消息正在写入第一条逻辑消息的一半。显然,这意味着接口失败,因为数据已损坏。
在套接字上使用的唯一特殊设置是
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() 没有按我期望的方式工作之外,我看不到任何明显的东西。根据我的理解,这是一个流,因此缓冲区写入需要完成,即使在调用结束时数据没有被推出套接字。
【问题讨论】:
-
和
Receive()一样,你必须检查Send()的返回值。并非所有字节都必须写入发送缓冲区(至少在非阻塞模式下)。 -
我们也看不到 GetLogicalMEssage。我希望您不希望收到与发送相对应的消息。它们可以被切成小块 - 但总是会按顺序到达(或根本不按顺序)
-
我将逻辑消息序列化到流中。在另一端,我读回逻辑消息并反序列化它们。我知道传输可以以奇怪的方式将它们送到那里,但保证流是有序的。
标签: c# multithreading sockets networking