唉!
我正在尝试获取一个ftp文件列表,并且已经有一个小型库可以做到这一点 . 事情是Socket.Receive()函数在收到所有数据之前不会阻塞 . 当我在该行设置断点时,它接收所有数据,但如果我不这样做,则只有38个字节(应该在380左右) .
这是代码:
While True
Dim bytes As Integer = cSocket.Receive(buffer, buffer.Length, SocketFlags.None)
mes += ASCII.GetString(buffer, 0, bytes)
If bytes < buffer.Length Then
Exit While
End If
End While
正如我所说:如果断点设置在带有.Receive部分的行中,它就可以工作 . 我可以使用一种解决方法来保证一个额外的循环,但这似乎非常脏 . 有任何想法吗?
//编辑:所以让我添加更多信息 . 我不知道我会收到多少数据 . 代码来自从ftp服务器接收数据的函数 . 我认为当消息以CRLF结束时我可以停止但我不能这样做,因为列出的每个文件之间都有一个CRLF . 示例:file1.textCRLFfile2.txtCLRFfile3.txtCRLF
有时当我调用receive时,即使有更多要列出的文件,它也会在结尾处返回一个带有CRLF的文件 . 所以这种情况对我来说似乎不稳定 .
1 回答
在这种情况下,您对"all data"究竟是什么意思?在套接字关闭之前,总会有更多数据 . 网络堆栈不知道或不关心某些数据在逻辑上属于一起 . 它会被切换成不同大小的IP数据包(由complex algorithms确定) .
对于您作为接收方,这意味着您将以块的形式获取正在接收的数据 . 您需要继续调用
Receive
,直到您知道自己拥有所需的所有数据为止 .从MSDN documentation(强调我的):
设置断点时看到不同行为的原因是因为在发送方发送数据时,您实际上是在暂停应用程序 . 操作系统仍将接收数据包并缓冲它们,直至某一点 . 标准缓冲区大小为8192字节,可以使用ReceiveBufferSize属性进行更改 .
代码
这如何在代码中翻译?假设您确实知道需要接收多少数据,改进的代码将如下所示:
循环中的条件消失了,因为我们没有收到很多字节,我们想继续阅读 .
bytesRemaining
保持仍然要接收的字节数的运行计数 .与您的问题无关,但我已将
mes
字符串连接替换为StringBuilder
. 可能你会创建很多新的字符串,所有人(除了最后一个)都需要进行垃圾回收 .