5

我需要使用 TCP 通过具有固定非标准 MTU(例如 1560)的子网发送一些数据。如果帧的长度小于 MTU,则通过该子网传输的所有以太网帧都应手动填充 0。

因此,数据大小应为 (1560 - sizeof( IP header ) - sizeof( TCP header ) )。

这就是我要做的方式:

  1. 我设置了 TCP_CORK 选项来减少数据碎片。它不可靠,因为有 200 毫秒的上限,但它有效。

  2. 我知道IP头的大小(20字节),所以数据长度应该等于(1540-sizeof(TCP头))。

  3. 那就是问题所在。我不知道 TCP 标头的大小。它的“选项”字段的大小是浮动的。

那么,问题来了:如何获取 TCP 标头的大小?或者也许有一些方法可以发送带有固定长度标头的 TCP 帧?

4

4 回答 4

10

在用户应用程序中使用 TCP 时试图控制帧的大小是错误的。您在错误的抽象级别上工作。这也是不可能的。

您应该做的是考虑用其他东西(UDP?)替换 TCP,或者,不太可能但可能,重写您的以太网驱动程序以设置非标准 MTU 并执行您需要的填充。

于 2011-05-31T14:43:44.993 回答
6

This isn't possible using the TCP stack of the host simply because a TCP stack that follows RFC 793 isn't supposed to offer this kind of access to an application.

That is, there isn't (and there shouldn't be) a way to influence what the lower layers do with your data. Of course, there are ways to influence what TCP does (Nagle for example) but that is against the spirit of the protocol. TCP should be used for what it's best at: transferring a continuous, ordered stream of bytes. Nothing more, nothing less. No messages, packets, frames.

If after all you do need to control such details, you need to look at lower-level APIs. You could use SOCK_RAW and PF_PACKET.

Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level.

@gby mentioned UDP and that is (partially) a good idea: UDP has a fixed size. But keep in mind that you will have to deal with IP fragmentation (or use IP_DONTFRAG).

于 2011-05-31T14:59:56.143 回答
2

除了我在 OP 问题下的评论之外,原始 RFC 中概述了如何通过以太网发送 TCP/IP 的引用是相关的:

RFC 894(强调我的):如有必要,应填充数据字段(八位字节为零)以满足以太网最小帧大小

如果他们希望所有以太网帧都达到最大尺寸,他们会这么说的。他们没有。

于 2011-05-31T17:30:28.157 回答
0

也许填充的意思是 TCP 标头填充以将其对齐 32 位应该全为零: http: //freesoft.org/CIE/Course/Section4/8.htm

于 2015-04-29T16:25:57.800 回答