I'm writing a C/C++ client-server program under Linux. Assume a message m is to be sent from the client to the server.
Is it possible for the client to read the TCP sequence number of the packet which will carry m, before sending m?
In fact, I'd like to append this sequence number to m, and send the resulting packet. (Well, things are more complicated, but let's keep it that simple. In fact, I'd l开发者_Go百科ike to apply authentication info to this sequence number, and then append it to m.)
Moreover,
is it possible for the server to read the TCP sequence number of the packet carrying m?
You can do something very nearly equivalent to this. You can count all the bytes you send and put a count of all the bytes sent before the message at the end of your message.
I get really nervous anytime anybody talks about 'packets' with TCP. Because if you talk about packets and TCP at the same time you are mixing protocol levels that shouldn't be mixed. There is no meaningful correspondence between data you send in TCP and the packets that are sent via IP.
Yes, there are sequence numbers in IP packets used to send TCP information. These sequence numbers are a count of the number of bytes (aka octets) sent so far. They identify where in the stream the bytes in the packet belong, but they are otherwise unrelated to the packet.
If a resend happens, or if you're using the Nagle algorithm, or if the TCP stack feels like it that day, you may end up with two send operations ending up in the same packet. Or, you might end up with half of one send operation ending up in one packet, and half in another packet. And each of those packets will have their own sequence numbers.
As I said, there is absolutely no meaningful relationship between send operations you perform at the transport layer and the packets sent at the network layer. I'm not talking theoretically either. It's not 'really all packets underneath and the send generally, barring some weird condition, puts all the bytes in a single packet'. No, the scenarios I outlined above where the bytes from a single send operation are spread to multiple packets happen frequently and under unpredictable conditions.
So, I don't know why you want to know anything about the sequence numbers in packets. But if you were using the sequence number as a proxy for number of bytes sent, you can keep that count yourself and just stuff it into the stream yourself. And remember to count those bytes too.
no, you can't do that -- at least not with expected result
This is because:
- TCP is stream based, not packet based.
- TCP sequence number is in byte, not packet.
- Underlying TCP layer do the segmentation for you.
- TCP window size / packet size are dynamic
These means you might send a "packet" with the sequence number at the end of "packet". It turns out, the underlying magics re-segment your packet.
What you want:
1 2 3 4
+---+---+---+---+
| A | B | C |"1"| packet 1, seq=1, len=4
+---+---+---+---+
5 6 7 8
+---+---+---+---+
| A | B | C |"5"| packet 2, seq=5, len=4
+---+---+---+---+
What you might get:
1 2 3 4
+---+---+---+---+
| A | B | C |"1"| packet 1 (seq=1, len=4)
+---+---+---+---+
(packet 1 got lost)
1 2 3 4 5 6
+---+---+---+---+---+---+
| A | B | C |"1"| A | B | packet 1, resent, seq=1, len=6
+---+---+---+---+---+---+
7 8
+---+---+
| C |"5"| packet 2, seq=7, len=2
+---+---+
TCP/IP stack does all the things for you. You receive only payload. Stack removes all the headers and provides payload at user space.
If you really want to add or modify at packet header level, try out RAW sockets
. RAW sockets receives/sends packet directly from Network card irrespective of transport type (TCP or UDP). In this case you have to strip/add all the headers (TCP/UDP Header, IP Header and Ethernet Header
) with your payload.
Checkout a very good video tutorial on RAW Sockets
精彩评论