【问题标题】:Losing Data at TCP transferTCP 传输时丢失数据
【发布时间】:2014-10-31 16:39:01
【问题描述】:

我的问题是通过 TCP 数据传输丢失数据。

我已经构建了一个基于 AVR 的自制网络服务器(或至少尝试过)。

我能够与客户端 PC(我的 PC)通信,并且我能够发送几行 HTML(总数据

但是当我想发送我的基本主页 (~1KB) 时,我只能在 WireShark 中获得 181 字节的数据。

我怀疑问题出在 TCP 的构造上。

以下数据为十六进制格式

来自客户端(我的电脑):

sequence number: de db c7 b1

ack number: 00 0a 00 0b

从服务器(AVR):

sequence number: 00 0a 00 0b

ack number: de b6 c9 18

总 TCP 长度:935 字节,IP 和 TCP 标头 20-20 字节

我设置错了什么设置?

【问题讨论】:

    标签: sockets tcp avr


    【解决方案1】:

    TCP 是一个流,不能保证每次发送都会产生一个接收信号。您需要重复调​​用 send 直到所有字节都发送完毕,另一方面,您还需要重复接收,在每个后续成功接收时将新数据附加到缓冲区的末尾......您不能忽略来自send/recv 调用,你必须用它来知道有多少数据被发送/recvd。

    【讨论】:

    • 我想我的问题还不清楚。我有一个大约 1KB 大的页面,所以它适合一个 TCP 数据包。此数据包是通过 AVR 正确生成的,但在传输 (LAN) 期间的某处仅收到 181 字节。我知道数据包可能会丢失,但是数据包的一部分呢?在局域网中?哦,我得到的大小总是 181 字节。
    • 没有TCP包,只有TCP流。在 TCP 中,您可以放心地忽略 MTU。但是你不能忽略 send 和 recv 的返回码。
    【解决方案2】:

    问题解决了!

    ENC28J60_CS();
    ENC28J60_CMD(WCR,ETXNDL);
    SPIWR(package_length);
    SPIWR(16+(package_length>>8));
    ENC28J60_DS();
    

    package_length 是一个整数,ETXNDL(寄存器)也是如此。 到目前为止,第二个 SPIWR() 函数只发送了值 16: SPIWR(16); 那么问题来了,我从来没有将package_length的高字节加到16,所以芯片总是发送1-255字节长的包。

    为什么是 16? RX 缓冲区从 0x0000 开始,到 0x0fff 结束。 TX 缓冲区从 0x1000 开始,到 0x1fff 结束。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-24
      • 2015-01-05
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      相关资源
      最近更新 更多