【问题标题】:TCP client receives packet sizes different than the server sendsTCP 客户端接收的数据包大小与服务器发送的不同
【发布时间】:2018-08-25 00:41:29
【问题描述】:

我的理解是 TCP 被认为是“可靠的”,因为接收方确认收到数据包并在有任何问题时请求重新发送。我的文件传输程序目前以 32767 字节的数据包发送文件,尽管我已经尝试过所有大小。发送需要 340 个数据包的 10 meg 文件始终会导致接收器上的三个或四个数据包明显小于发送的数据包。我总是得到一个与原始文件略有不同的文件。

例如,我的日志记录了所有收到的数据包的大小:

TCP packet received (32767 bytes)
TCP packet received (32767 bytes)
TCP packet received (14600 bytes)
TCP packet received (32767 bytes)

我的发送线程以 32767 字节块读取文件并调用发送子:

MyFile.Read(Buffer, 0, BufferSize)
SendTCPData(Address, Buffer)

我的 TCP 代码很简单:

Shared Sub SendTCPData(Address As String, ByVal Data As Byte())
    Dim Client As New TcpClient(Address, PortNumber)
    Dim Stream As NetworkStream = Client.GetStream()
    Stream.Write(Data, 0, Data.Length)
    Stream.Close()
    Client.Close()
End Sub

有人可以帮忙吗? (“TCP 客户端到服务器通信”一文没有涉及如何处理接收到的数据包大小,这是我的问题。)

【问题讨论】:

  • 你如何发送 32KB - 1byte...为什么是 32767?为什么不是像 32768 这样的偶数?即使在那里,您也应该考虑 IP 标头以适应这样的固定大小缓冲区。它不会阻止您遇到问题。您在上传期间从不校验您的文件?与其转储文件并假设 TCP 将无错误地控制流,不如向客户端发送 ACK 以发送下一个数据包。如果您不想为了速度而对每个数据包都进行处理,那么您应该对它们进行编号以便能够重新发送损坏的数据包。
  • TCP 是面向字节的。当你给 TCP 层一个 32767 字节的块时,它将把它分成多个段,在不同的数据包中发送。如何将接收到的数据写入文件?
  • 32767 在我找到的示例代码中使用。它只是无符号 16 位值的最大大小,有点随意。我的(简化的)接收代码如下所示。每次收到数据包时都会调用它:
  • 您的代码的问题在于它假定一个发送=一个接收,这是不正确的。 TCP 是一种流式协议,这意味着它在应用层没有数据包的概念。当您调用 Read() 时,它会读取它下载的所有内容到目前为止,因此这可能小于实际数据的大小(这是您遇到的问题经历)。我的代码通过跟踪每个“数据包”包含多少数据来解决这个问题,并且在读取整个数据包之前它不会将数据传递给您。有关其工作原理的信息,请参阅:stackoverflow.com/a/37352525

标签: vb.net sockets tcp


【解决方案1】:

TCP 不向应用程序提供数据包接口,它提供字节流接口。 TCP not 将字节“粘合”到消息中——它不是消息协议。如果您想要使用 TCP 读取和写入消息的代码,则必须实际编写它或使用其他人的代码。

如果您知道发送方正在发送准确的 32,767 字节,只需继续调用 TCP 接收函数,直到您收到 32,767 字节。如果您不确切知道发送方将发送多少字节,或者无法使用某种标记来识别数据的结尾,那么您就无法知道您何时收到了所有字节。

对于将来,在您编写任何网络代码之前,值得花时间记录您将要使用的协议。查看 TCP 上的现有协议(例如 SMTP、NNTP、FTP 或 HTTP)的一些规范,了解您需要决定和记录的内容。

如果您通过 TCP 发送文件,请仔细查看一些通过 TCP 发送文件的标准(例如 FTP),然后实施该标准或选择其合理的子集。至少,阅读该标准将使您了解需要做出哪些类型的决定才能最终获得一个有效的协议。此外,它对于调试也很重要——如果程序无法运行,如果没有标准,就很难确定是服务器还是客户端出了问题,因为没有可比较它们的参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 2019-08-05
    相关资源
    最近更新 更多