Sending TCP frames of fixed length

2019-05-02 03:09发布

I need to send some data over the subnet with fixed non-standard MTU (for example, 1560) using TCP. All the Ethernet frames transfered through this subnet should be manually padded with 0's, if the frame's length is less than MTU.

So, the data size should be (1560 - sizeof( IP header ) - sizeof( TCP header ) ).

This is the way I am going to do it:

  1. I set the TCP_CORK option to decrease the fragmenting of data. It is not reliable, because there is 200 millisecond ceiling, but it works.

  2. I know size of IP header (20 bytes), so data length should be equal to (1540 - sizeof( TCP header )).

  3. That's the problem. I don't know the TCP header size. The size of it's "Options" field is floating.

So, the question is: how to get the size of TCP header? Or maybe there is some way to send TCP frames with headers of fixed length?

4条回答
冷血范
2楼-- · 2019-05-02 03:41

Maybe what was meant by padding is that the TCP header padding to align it on 32 bits should be all zeros : http://freesoft.org/CIE/Course/Section4/8.htm

查看更多
3楼-- · 2019-05-02 03:46

Trying to control the size of frames when using TCP from the user application is wrong. You are working at the wrong abstraction level. It's also impossible.

What you should be doing is either consider replacing TCP with something else (UDP?) or, less likely, but possible, rewrite your Ethernet driver to set the non standard MTU and do the padding you need.

查看更多
叛逆
4楼-- · 2019-05-02 03:55

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).

查看更多
Deceive 欺骗
5楼-- · 2019-05-02 03:56

In addition to my comments below the OP's question, this quote from the original RFC outlining how to send TCP/IP over ethernet is relevant:

RFC 894 (emphasis mine): If necessary, the data field should be padded (with octets of zero) to meet the Ethernet minimum frame size.

If they wanted all ethernet frames to be at maximum size, they would have said so. They did not.

查看更多
登录 后发表回答