-------------------------------------------------------------
|ip header|tcp header(or x header)| data |
-------------------------------------------------------------
用recvfrom收到的数据包括一个IP头,一个相应的协议头,然后是数据(数据也可以为空,就看实际情况了). 但当我们发送IP包的时候,却不用亲自处理IP包头,只需要填 充参数protocol所指定的相应的协议头即可.也就是说,用sendto的时候,我们提供给它的缓冲区数据是从IP包头的第一个字节开始,如下,只需要构造这么一个缓冲区就可以了.
------------------------------------------------------------
|tcp header(or udp header or x header)| data |
------------------------------------------------------------
如果想自己也想亲自处理IP头,则需要IP_HDRINCL的socket选项.如下:
int flag = 1;
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(int));
这样,发送时所要提供的缓冲区有成如下形式:
------------------------------------------------------------
|ip header|tcp header(or x header)| data |
------------------------------------------------------------
但是,即时是这种情况,在我们发送IP包的时候.也不是填充ip头的所有字段,而是应该将ip头的id(identification)字段设置为0,表示让内核来处理这个字段.同时,内核还帮你完成ip头的校验和的计算,并随后填充check字段.