In the network programming, most of the time is the kernel filled with the message header, and then we fill in the data section to send. But if it is not the TCP/IP protocol, or some other reason, we need to fill the header of the message ourselves. In filling the message, the first is to understand the structure of the message header.
The following is the structure of the IP headers and the structure of the IP header, respectively, refer to RFC791 and RFC793.
Also incidentally read the next UDP protocol introduction, refer to RFC768. There was a question that UDP should come out after the IP protocol to solve the disadvantage of TCP, why the RFC number is so much earlier than IP and TCP. So the search for some history did not get results, and finally in the RFC documents to find the answer, the original 791 and 793 are 760 and 761 respectively, the upgrade version. Now it seems a little more reasonable.
Now that we've solved the little doubt, go ahead. When we send the data using the TCP/IP protocol, it is the IP header and the tcp/header and the data section.
Understand the format of the head, and then look at the structure of the head in the library file definition
struct IPHDR
{
#if __byte_order = = __little_endian
unsigned int ihl:4; The length of the header
unsigned int version:4; Protocol version number, 4/6, represents Ipv4/ipv6
#elif __byte_order = = __big_endian
unsigned int version:4;
unsigned int ihl:4;
#endif
u_int8_t tos; Type of service field
u_int16_t Tot_len; The total length of the IP packet
u_int16_t ID; Identification field
u_int16_t Frag_off; Fragment offset segment offset,
u_int8_t ttl; Time to Live has a maximum of 255, minus 1
u_int8_t protocol per route; Protocol such as TCP is 6,UDP is 8,icmp is 1, there is a definition
u_int16_t check in in.h; The first checksum
u_int32_t saddr; Source IP address
u_int32_t daddr; Destination IP address
/*the options start here. */
};
struct TCPHDR
{
u_int16_t source; Source port number
u_int16_t dest; Destination port number
u_int32_t seq; The starting byte number of the data in the whole message
u_int32_t ack_seq; The next byte to be received
u_int16_t Res1:4; Reserved word
u_int16_t doff:4; TCP header length
u_int16_t fin:1; Used to release a link
u_int16_t syn:1; Synchronization sequence number, used to initiate the link
u_int16_t rst:1; Resets a confusing link to
u_int16_t psh:1; Send data to the application u_int16_t Ack:1 immediately after receiving the data
; 1 means Ack_seq is valid, 0 means ack_seq should be ignored
u_int16_t urg:1; Emergency pointer
u_int16_t res2:2; This is not found in the format, also did not find out what the role of
u_int16_t window; The size of the sliding window
u_int16_t check; Checksum
u_int16_t urg_ptr; Just the location of the emergency data in the current data segment
};
Some of the judgment sizes in TCPHDR are too long and have been deleted.
The interpretation of the data field is also relatively concise, the detailed explanation forgets when can consult other material, the short text may play the role of the hint. I haven't studied for a good while.