我需要使用TCP在具有固定非标准MTU(例如,1560)的子网上发送一些数据。 如果帧的长度小于MTU,则通过该子网传输的所有以太网帧都应手动填充为0。
所以,数据大小应该是 (1560 - sizeof(IP头) - sizeof(TCP头))。
这就是我要这样做的方式:
我设置了TCP_CORK选项以减少数据的分段。它不可靠,因为有200毫秒的天花板,但它可以工作。
我知道IP头的大小(20字节),因此数据长度应该等于(1540 - sizeof(TCP头))。
这就是问题所在。我不知道TCP头大小。它的“选项”字段的大小是浮动的。
所以,问题是:如何获得TCP头的大小?或者也许有一些方法可以发送带有固定长度标头的TCP帧?
答案 0 :(得分:10)
尝试在用户应用程序中使用TCP时控制帧的大小是错误的。您正在以错误的抽象级别工作。这也是不可能的。
你应该做的是考虑用其他东西替换TCP(UDP?),或者不太可能,但可能,重写你的以太网驱动程序来设置非标准MTU并做你需要的填充。
答案 1 :(得分:6)
使用主机的TCP堆栈是不可能的,因为遵循RFC 793的TCP堆栈不应该提供对应用程序的这种访问。
也就是说,没有(也不应该)影响较低层对数据的影响。当然,有一些方法可以影响TCP
所做的事情(例如Nagle),但这违反了协议的精神。 TCP
应该用于最好的方法:传输连续的,有序的字节流。没有更多,没有更少。没有消息,数据包,帧。
如果毕竟 需要控制此类详细信息,则需要查看较低级别的API。您可以使用SOCK_RAW
和PF_PACKET
。
数据包套接字用于接收或 在设备驱动程序发送原始数据包 (OSI第2层)级别。
@gby提到了UDP,这是(部分)一个好主意:UDP
具有固定的大小。但请记住,您必须处理IP碎片(或使用IP_DONTFRAG
)。
答案 2 :(得分:2)
除了我在OP的问题下面的评论之外,原始RFC的引用概述了如何通过以太网发送TCP / IP是相关的:
RFC 894(强调我的): 如有必要,应填充数据字段(八位字节为零)以满足以太网最小帧大小。
如果他们希望所有以太网帧都达到最大值,他们就会这样说。他们没有。