2014-03-05 41 views
0
// message buffer 
Byte[] dataByte = new Byte[RES_SIZE]; 
int readedBytes = 0; 

do // wait.... 
{ 
    Thread.Sleep(Delay); 
    message = string.Format("Waiting for messages, check number #{0}", readedBytes); 

} while (!networkStream.DataAvailable); 
// 
// check for message 
if (networkStream.DataAvailable) 
{ 
    readedBytes = networkStream.Read(dataByte, 0, RES_SIZE); 
    //... 
    //... 
    //... 
} 

我与微软有关以前的代码建议的文件,那就是:微软建议套接字


此代码明确地依赖于NetworkStream.DataAvailable财产。虽然这并非不正确,但它不是非常有效,因为它强制代码在嵌套Thread.Sleep()调用的循环中测试此属性, 可以增加线程上下文切换次数/秒,并且可能导致到有点 增加CPU使用率。

此外,这并不意味着没有使用Socket.ReceiveTimeout值,因为套接字配置为阻塞模式,因此NetworkStream.Read()调用可能会阻塞。

上述代码的第二个问题是它假定一个Read()操作将读取整个主机响应。虽然这对小读取可能是正确的,但这是由Socket API保证的而不是,并且可能导致部分读取。

如果数据连接器不具备主机通信协议的内部知识,这将非常难以处理,因为它需要能够解释从套接字读取的数据以检测响应消息是否被完全读取。另外,如果发生部分读取,一旦引入了连接池,这可能会导致严重的问题。考虑以下情况:

  • 网站上的事务从池中获取新连接并向主机发送请求。
  • 主机回复1526字节的响应。
  • Connection对象尝试从套接字读取,但只读取1345个字节。
  • 由于连接认为它从套接字读取了整个响应,它将连接返回到池并继续。

现在,想象一下,当网站上的第二个交易出现时,请求从池中 连接,并获得在第一种情况下使用相同的连接发生了什么:

  • 的代码获得连接池并向主机发送新的请求消息
  • 主机通过响应回复新的1520
  • 连接尝试从套接字读取并获取1701个字节。

也就是说,它获得了第一个调用期间最初未读取的剩余181个字节,以及第二个操作完成的 完整响应。当调用者尝试解析主机响应并发现它不正确时,这可能会导致错误。

建议 强烈建议,以避免依赖于套接字中读取由主机, 同时会出现这种情况大部分在正常情况下的时间发送整个信息,这很容易负载或 网络拥塞下破裂。


有了这个介绍,我一直在寻找如何解决这个问题,但是,所有的例子使用了一个我用同样的解决方案。

do // wait.... 
{ 
    // 
    // 
    // 
} while (!networkStream.DataAvailable); 

问题: 我该如何解决这个问题?

+0

另外,'DataAvailable'上的while循环对除了网络流以外的几乎任何流都很有用,因为几乎总是读取速度比发送所有字节的速度快。 – Silvermind

+0

@Silvermind通过强制上下文切换,Thread.Sleep可以确保CPU负载增加。 –

+0

@ElCote你在哪里得到这个“微软推荐”文档? Thread.Sleep几乎总是做错的方法。 –

回答

0

读取套接字中的SELECT方法。它需要一个套接字列表并返回具有可用数据的列表。

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.select(v=vs.110).aspx

这可以让你有一个循环检查X插槽,然后处理与在单独的线程/任务数据的人。

http://books.google.pl/books?id=2zT5b2BS1OUC&pg=PA96&lpg=PA96&dq=socket.select+example+c%23&source=bl&ots=_JZzZY1zzQ&sig=AnGpQbL_GP2MR3Yk4oHNzJAqwU4&hl=en&sa=X&ei=fGgXU-frDorLsgas_YDwCw&ved=0CDwQ6AEwAw#v=onepage&q=socket.select%20example%20c%23&f=false

实际上有一些很好的讨论。本书摘自“C#中的TCP/IP套接字:程序员实用指南”一书。