没有通过networkstream.read接收所有数据

时间:2011-12-11 14:51:18

标签: vb.net tcpclient

我正在使用以下代码从服务器获取新闻组:

sendBytes = Encoding.ASCII.GetBytes("LIST active microsoft.public*" & ControlChars.CrLf)
networkStream.Write(sendBytes, 0, sendBytes.Length)
Array.Clear(bytes, 0, bytes.Length)
If networkStream.CanRead Then
    Do
        numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length)
        myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))
        intLenMyReadBuf = myReadBuffer.Length
        intLenComplMsg = myCompleteMessage.Length
        swWriter.WriteLine("buf len = " & intLenMyReadBuf & ", msg len = " & intLenComplMsg)
        Loop While networkStream.DataAvailable
Else
    Console.WriteLine("Sorry.  You cannot read from this NetworkStream.")
End If

sendBytes = Encoding.ASCII.GetBytes("QUIT " & ControlChars.CrLf)
networkStream.Write(sendBytes, 0, sendBytes.Length)
tcpClient.Close()
networkStream.Close()

当我执行代码时,例程只接收一个数据块。但是,如果我进入 调试模式在循环指令处有一个断点,我收到所有的数据块 我是否遗漏了代码中的某些内容,例如等待或其他内容,这将使程序成为可能 接收调试时发生的所有数据?

1 个答案:

答案 0 :(得分:1)

问题是你循环直到networkStream.DataAvailable不成立。在正在运行的应用程序中,您的循环可以执行得如此之快,以至于发送方没有时间再次填充缓冲区。

您需要循环直到满足特定条件。例子:

1)您收到的所有数据都已收到

2)已收到一组特定数据(即EOF)

3)已达到特定时限(即如果您未收到任何数据30秒,则保释)。如果你处于一个无限循环中,你应该总是实现这样的东西,除非你打算让这个过程永远持续下去。

我会将处理更改为:

Dim fLoopDone As Boolean
' Initialize the timestamp for the last data that was read so that we wait up to 30 seconds
' at the start for data.
Dim dtLastData As DateTime = Date.Now
Do
    ' Only process the data if there is some available.
    If networkStream.DataAvailable Then
        numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length)
        myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead))
        intLenMyReadBuf = myReadBuffer.Length
        intLenComplMsg = myCompleteMessage.Length
        swWriter.WriteLine("buf len = " & intLenMyReadBuf & ", msg len = " & intLenComplMsg)

        ' Record the last time that we received data
        dtLastData = Date.Now

        ' Possibly add a check in here to see if you are done reading.
    Else
        ' If more than 30 seconds has elapsed since the last data arrived, break out of the loop
        If Date.Now.Subtract(dtLastData).TotalSeconds > 30 Then
           fLoopDone = True
        End If
    End If
Loop While Not fLoopDone