包含在/usr/src/linux/include/linux/tcp.h
struct tcphdr { __be16 source; __be16 dest; __be32 seq; __be32 ack_seq; #if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #else #error "Adjust your <asm/byteorder.h> defines" #endif __be16 window; __be16 check; __be16 urg_ptr; };
tcphdr->source
16位源端口
tcphdr->dest
16位目的端口
tcphdr->seq
表示此次发送的数据在整个报文段中的起始字节数。序号是32位bit的无符号数。为了安全起见,它的初始值是一个随机生成的数,它到达32位最大值后,又从零开始。
tcphdr->ack_seq
指定的是下一个期望接收的字节,而不是已经正确接收的最后一个字节。
tcphdr->doff
TCP头长度,指明了TCP头部包含了多少个32位的字。此信息的必须的,因为option域的长度是可变的,所有整个TCP头部的长度也是可变的。从技术上讲这个域实际上指明了数据部分在段内的起始地址(以32位字作为单位进行计量),因为这个数值正好是按字为单位的TCP头部的长度,所以,二者的效果是等效的。
tcphdr->res1
保留位
tcphdr->window
16位滑动窗口大小,单位为字节,起始于确认序号字段指明的值,这个值是接收端期望接收的字节数,其最大值为63353字节。
TCP中的流量控制是同一个可变大小的滑动窗口来完成的。window域指定了从被确认的字节算起可以接收多少个字节。window=0也是合法的,相当于说到现在为止多达ack_seq-1个字节已经接收到了,但是接收放现在状态不佳,需要休息一下,等一会再接收更多的数据。以后接收方可以通过发送一个同样ack_seq但是window不为0的数据段,告诉发送方继续发送数据段。
tcphdr->check
校验和,覆盖了整个tcp报文端,是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
tcphdr->urg_ptr
这个域被用来指示紧急数据在当前数据段中的为止,它是一个相当于当前序列号的字节偏移量。这个设置可以代替中断信息。
fin、syn、rst、psh、ack、urg为6个标志位,含义如下:
tcphdr->fin :释放一个连接,它表示发送方已经没有数据要传输了。
tcphdr->syn :同步序号,用来发送一个连接。syn被用于建立连接的过程,在连接请求中,syn=1;ack=0表示该数据段没有使用捎带的确认域。连接应答捎带了一个确认,所以有syn=1;ack=1。本质上,syn位被用于表示connection request和connection accepted,然而进一步用ack位来区分这两种情况。
tcphdr->ret :该位用于重置一个混乱的连接,之所以混乱,可能是因为主机崩溃或者其他原因。该位也可以被用来拒绝一个无效的数据段,或者拒绝一个连接请求,一般而言,如果你得到的数据段设置了rst位,说明你这一端有了问题。
tcphdr->ack :ack位被设置为1表示tcphdr->ack_seq是有效的,如果ack为0,则表示该数据段不包含确认信息,所以tcphdr->ack_seq域应该被忽略。
tcphdr->urg :紧急指针有效
tcphdr->ece :用途暂时不明
tcphdr->cwr :用途暂时不明