2010-04-07 108 views
-1

下面的代码块时并行至4-5线程运行良好,但作为启动的线程的数目某处增加超过10个并发线程Socket.Recieve失败当多线程

int totalRecieved = 0; 
int recieved; 
StringBuilder contentSB = new StringBuilder(4000); 
while ((recieved = socket.Receive(buffer, SocketFlags.None)) > 0) 
{ 
    contentSB.Append(Encoding.ASCII.GetString(buffer, 0, recieved)); 
    totalRecieved += recieved; 
} 

Recieve方法返回失败零字节被读取,如果我继续调用接收方法,那么我最终会得到异常'已建立的连接被主机中的软件中止'。所以我假设主机实际上发送了数据然后关闭了连接,但由于某种原因,我从未收到过它。

我很好奇为什么当有很多线程出现这个问题。我认为它必须与这样一个事实有关,即每个线程的执行时间不会太多,因此导致此错误的线程有一些空闲时间。只是不知道为什么空闲时间会导致套接字不能接收任何数据。

编辑:只是为了澄清。每个线程都有自己的个人套接字读取不同的数据。

+0

要明确一点,每个线程都有自己的套接字? – 2010-04-07 20:14:47

+0

我不清楚的是,如果你有很多线程每个线程读一个套接字或一个套接字? – ParmesanCodice 2010-04-07 20:15:24

+0

你知道SocketError代码(SocketException.ErrorCode)吗?可能是一个超时... – ParmesanCodice 2010-04-07 20:30:16

回答

0

问题是尝试在多个线程的同一个套接字上使用Receive。

Socket class的MSDN文档特别建议在执行期间,一个套接字的Receive方法只能由单个线程和一个线程使用。

对于需要使用多个线程从同一套接字读取数据时,就应该把应用程序:

  • 使用BeginReceiveEndReceive的建议,MSDN,或者

  • 使用一个单一的插座读线程接收数据包,然后将每个数据包写入同步队列。您可能会有多个线程将数据从队列中提取出来。

+0

好点。猜猜我会改变为异步方法。仍然不明白为什么同步方法会失败。 – 2010-04-07 20:26:23

+0

MSDN特别声明,您不应该使用“接收”处理与多个线程的通信。由于线程的执行是非确定性的,它们的实现可能恰好(或似乎)以少于4个线程正常工作。 – 2010-04-07 20:47:07

+3

MSDN的写法有点令人困惑,当你有多个线程时使用'Receive'并不是问题。这个问题试图在多个线程的同一套接字上使用'Receive'。如果每个线程正在处理不同的套接字,那么在两个不同的线程上使用它就没有问题。 – 2010-04-08 05:25:50

1

打开的连接有系统限制,请参阅启动器this SO question。这里有一些more info

+0

由于@ Qua未显示Socket对象是如何构造的,因此可能会触及此限制。 – 2010-04-08 02:35:26

+1

我增加了一个新的答案,因为接受的答案是错误的。许可限制为10只适用于由MS提供的应用程序协议。还有其他一些原因也是10 ...您的其他链接更好,因为它提供了其中一些链接(例如,不超过10个半开放TCP连接,在1秒内不超过10个新连接)。 – 2010-04-08 05:28:33

+0

@Kevin:我知道有关于此的更好的Q + A,但我找不到它们) - : – 2010-04-08 08:32:54