【问题标题】:Why does my pc send more than 1514 byte packet in one go为什么我的电脑一次发送超过 1514 字节的数据包
【发布时间】:2022-01-28 05:29:52
【问题描述】:

我编写了一个程序,使用 TCP 客户端和服务器连续发送 1460 字节数据。我的系统接口MTU是1500。

这是我的客户程序

if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
{
  printf("\n Error : Could not create socket \n");
  return 1;
}
setsockopt(sockfd,SOL_TCP,TCP_NODELAY,&one,sizeof(one));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(9998);
serv_addr.sin_addr.s_addr = inet_addr("10.10.12.1");

if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
{
  printf("\n Error : Connect Failed \n");
  return 1;
}

while(1)
{
   write(sockfd, send_buff, 1448) ;

}

在 Wireshark 中,最初的 15 到 30 个数据包显示 1514 字节的数据包正在传输,但随后显示如下

一些数据包的wireshark输出

No.     Time        Source                Destination           Protocol Length Info
 16 0.000000    10.10.12.2            10.10.12.1            TCP      5858   53649 > distinct32 [ACK] Seq=3086892290 Ack=250285353 Win=14608 Len=5792 TSval=23114307 TSecr=23833274

Frame 16: 5858 bytes on wire (46864 bits), 5858 bytes captured (46864 bits)
Ethernet II, Src: 6c:3b:e5:14:9a:a2 (6c:3b:e5:14:9a:a2), Dst: Ibm_b5:86:85 (00:1a:64:b5:86:85)

Internet Protocol Version 4, Src: 10.10.12.2 (10.10.12.2), Dst: 10.10.12.1 (10.10.12.1)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
Total Length: 5844
Identification: 0x8480 (33920)
Flags: 0x00
Fragment offset: 0
Time to live: 64
Protocol: TCP (6)
Header checksum: 0xb38d [correct]
Source: 10.10.12.2 (10.10.12.2)
Destination: 10.10.12.1 (10.10.12.1)

Transmission Control Protocol, Src Port: 53649 (53649), Dst Port: distinct32 (9998), Seq: 3086892290, Ack: 250285353, Len: 5792
Source port: 53649 (53649)
Destination port: distinct32 (9998)
[Stream index: 0]
Sequence number: 3086892290
[Next sequence number: 3086898082]
Acknowledgement number: 250285353
Header length: 32 bytes
Flags: 0x010 (ACK)
Window size value: 913
[Calculated window size: 14608]
[Window size scaling factor: 16]
Checksum: 0x42dd [validation disabled]
Options: (12 bytes)
    No-Operation (NOP)
    No-Operation (NOP)
    Timestamps: TSval 23114307, TSecr 23833274

Data (5792 bytes)

在 wireshark 上显示超过 5792、7000、65535 字节的数据包正在传输。 但是我一次发送了 1514 个字节的数据包。另一方面,由于网络 mtu,我收到 1514 字节的数据包。

所以我的问题是

为什么会有这么多大数据包?

我也试过不使用 NODELAY 选项,但它不起作用。

有没有什么办法可以发送特定的数据包大小(比如 1514 字节),不能发送巨型帧?

我也为 tcp 发送缓冲区和接收缓冲区更新了我的 tcp_rmem 和 tcp_wmem。但没有找到任何解决方案。

【问题讨论】:

  • TCP 是一种字节传输服务,因此不能传输大于一个字节的消息。如果您想通过 TCP 连接传输大于一个字节的消息,则需要在顶部使用另一个协议。
  • TCP 一次可以传输多个字节。事实上,这样使用会更快。

标签: c sockets networking tcp tcpclient


【解决方案1】:

按照设计,TCP 将多个 write() 调用捆绑到更大的数据包中。另外,默认情况下,TCP 根据Nagle's Algorithm 合并数据包。

如果您想更好地控制网络数据包的实际大小,请使用 UDP。

【讨论】:

  • 为了禁用 nagle 算法,我在 setsockopt 中使用了 TCP_NODELAY。但它不工作。在我们的项目中,我们必须使用具有特定数据包大小的 tcp。
  • TCP 不能也不保证任何特定的数据包大小。如果这确实是您的要求,那么该要求是无效的,因为 TCP 不是这样工作的。
【解决方案2】:

这些是“巨型帧”,它们比传统的帧大小更快,因为它们不会给 CPU 带来太多负载。

认为你自己很幸运,你得到了它们,而不用担心你的 IP 堆栈设置。

【讨论】:

  • 顺便说一句,TCP 不是“面向消息的”。所以你需要以某种方式构建你的数据,比如为一个数据块添加一个网络顺序长数据长度的前缀,或者作为换行符终止的 ASCII 或其他东西。
  • 请参阅stromberg.dnsalias.org/~strombrg/TCP 以获得更完整的解释。完全披露:我写的。
【解决方案3】:

我查了很多,发现,我们需要在界面上更改一些参数。

在我的界面 eth0 默认选项是

Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

现在使用 ethtool 我们需要关闭一些发送端分段卸载。 为了那个原因 sudo ethtool -K eth0 tso off gso off

使用这个

Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

在此之后,您的界面将发送您想要发送的任何数据包。

【讨论】:

  • 无论您更改什么参数,TCP 仍然无法以这种方式工作。无法保证这会导致您想要的行为。
  • 亲爱的格雷格!!谢谢你!!有了这个,tcp 数据包正在根据我的 mtu 发送。接口上的所有数据包工作卸载。所以它不会合并并放在一个数据包中。
猜你喜欢
  • 2021-04-06
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
相关资源
最近更新 更多