Socket.Receive什么时候返回数据?

时间:2013-03-20 12:47:43

标签: c# sockets

初学者问题:不久前我问过的一个问题的跟进。

我正在尝试理解这个同步套接字教程http://msdn.microsoft.com/en-us/library/6y0e13d3.aspx,特别是下面代码中的一行。

问题: 我想确保我正确理解程序流程。 执行handler.Receive(bytes)时返回?当它“溢出”并且收到的字节超过1024字节时,它是否返回并存储 int bytesRec **中收到的字节数? **如果是这样,这可能听起来很愚蠢,如果更多字节到达会发生什么,因为它将1024字节存储在* data *变量中而不是监听更多字节可能在那个时候到达?或者我不应该担心它并让.net处理这个问题吗?

Socket handler = listener.Accept();
data = null;

// An incoming connection needs to be processed.
while (true) {
    bytes = new byte[1024];
    int bytesRec = handler.Receive(bytes);
    // My question is WHEN does the following line
    // get to be executed
    data += Encoding.ASCII.GetString(bytes,0,bytesRec);
    if (data.IndexOf("<EOF>") > -1) {
        break;
    }
}

1 个答案:

答案 0 :(得分:11)

  

handler.Receive(bytes)何时返回?

文档:

  

如果没有可用于读取的数据,则Receive方法将被阻止   直到数据可用,除非使用设置了超时值   Socket.ReceiveTimeout。如果超出超时值,则接收   call会抛出一个SocketException。如果您处于非阻塞模式,   并且协议栈缓冲区中没有可用的数据,   Receive方法将立即完成并抛出一个   SocketException。您可以使用Available属性来确定是否   数据可供阅读。当Available为非零时,重试   接受手术。


  

它是否返回并存储int中接收的字节数   bytesRec何时“溢出”并且收到的字节数超过1024字节?

不,它总是返回已读取的字节数。如果没有,你怎么知道bytes中哪些部分包含有意义的数据以及它的哪些部分未被使用?

非常重要了解套接字通常如何工作:字节可能会到达数据包,但就接收器而言每个字节都应该独立考虑。这意味着无法保证您将获取发件人发送的块中的字节,当然也不能保证有足够的数据来填充缓冲区。

如果您只想处理1024字节块中的传入数据,那么在您向对象释放1024字节之前,继续调用Receive是您自己的责任。

  

如果是这样,这可能听起来很愚蠢,如果更多会发生什么   字节到达,因为它将1024个字节存储在变量和   不听那些可能在那时到达的更多字节?

让我们重申Receive不会在缓冲区中存储1024个字节,因为这是缓冲区的大小。它会存储最多 1024字节。

如果网络堆栈内部缓冲的数据多于缓冲区可容纳的数据,则会返回1024个字节,其余的将保留在网络堆栈的缓冲区中,直到再次调用Receive为止。如果Receive已经开始将数据复制到缓冲区,那时会从网络收到更多数据,那么很可能会发生的情况是,这些数据必须等待下一次Receive调用。

毕竟,在任何时候都没有人提供Receive能够为你提供所有数据的保证(虽然当然这是可取的,但大多数情况都是如此)时间)。