我正在使用以下代码从服务器获取新闻组:
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()
当我执行代码时,例程只接收一个数据块。但是,如果我进入 调试模式在循环指令处有一个断点,我收到所有的数据块 我是否遗漏了代码中的某些内容,例如等待或其他内容,这将使程序成为可能 接收调试时发生的所有数据?
答案 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