/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;
};
|----------------|----------------|-------------
| source | dest |
|----------------|----------------|
| seq |
|---------------------------------|
| ack_seq | 20 Bytes
|----|----|------|----------------|
|doff|res1| | window |
|----|----|------|----------------|
| check | urg_ptr |
|----------------|----------------|-------------
| options | 4 Bytes
|---------------------------------|
TCP頭
tcphdr->source
16位源端口號
tcphdr->dest
16位目的端口號
tcphdr->seq
表示此次發(fā)送的數(shù)據(jù)在整個報(bào)文段中的起始字節(jié)數(shù)。序號是32 bit的無符號數(shù)。為了安全起見,它的初始值是一個隨機(jī)生成的數(shù),它到達(dá)32位最大值后,又從零開始。
tcphdr->ack_seq
指定的是下一個期望接收的字節(jié),而不是已經(jīng)正確接收到的最后一個字節(jié)。
tcphdr->doff
TCP頭長度,指明了在TCP頭部包含多少個32位的字。此信息是必須的,因?yàn)閛ptions域的長度是可變的,所以整個TCP頭部的長度也是變化的。從技術(shù)上講,這個域?qū)嶋H上指明了數(shù)據(jù)部分在段內(nèi)部的其起始地址(以32位字作為單位進(jìn)行計(jì)量),因?yàn)檫@個數(shù)值正好是按字為單位的TCP頭部的長度,所以,二者的效果是等同的
tcphdr->res1為保留位
tcphdr->window
是16位滑動窗口的大小,單位為字節(jié),起始于確認(rèn)序列號字段指明的值,這個值是接收端正期望接收的字節(jié)數(shù),其最大值是63353字節(jié)。
TCP中的流量控制是通過一個可變大小的滑動窗口來完成的。window域指定了從被確認(rèn)的字節(jié)算起可以接收的多少個字節(jié)。window = 0也是合法的,這相當(dāng)于說,到現(xiàn)在為止多達(dá)ack_seq-1個字節(jié)已經(jīng)接收到了,但是接收方現(xiàn)在狀態(tài)不佳,需要休息一下,等一會兒再繼續(xù)接收更多的數(shù)據(jù),謝謝。以后,接收方可以通過發(fā)送一個同樣ack_seq但是window不為0的數(shù)據(jù)段,告訴發(fā)送方繼續(xù)發(fā)送數(shù)據(jù)段。
tcphdr->check
是檢驗(yàn)和,覆蓋了整個的TCP報(bào)文段,這是一個強(qiáng)制性的字段,一定是由發(fā)送端計(jì)算和存儲,并由接收端進(jìn)行驗(yàn)證。
tcphdr->urg_ptr
這個域被用來指示緊急數(shù)據(jù)在當(dāng)前數(shù)據(jù)段中的位置,它是一個相對于當(dāng)前序列號的字節(jié)偏移值。這個設(shè)施可以代替中斷信息。
fin, syn, rst, psh, ack, urg為6個標(biāo)志位
這6個位域已經(jīng)保留了超過四分之一個世紀(jì)的時(shí)間而仍然原封未動,這樣的事實(shí)正好也說明了TCP的設(shè)計(jì)者們考慮的是多么的周到。它們的含義如下:
tcphdr->fin fin位被用于釋放一個連接。它表示發(fā)送方已經(jīng)沒有數(shù)據(jù)要傳輸了。
tcphdr->syn 同步序號,用來發(fā)起一個連接。syn位被用于建立連接的過程。在連接請求中,syn=1; ack=0表示該數(shù)據(jù)段沒有使用捎帶的確認(rèn)域。連接應(yīng)答捎帶了一個確認(rèn),所以有syn=1; ack=1。本質(zhì)上,syn位被用來表示connection request和connection accepted,然而進(jìn)一步用ack位來區(qū)分這兩種情況。
tcphdr->rst 該為用于重置一個已經(jīng)混亂的連接,之所以會混亂,可能是由于主機(jī)崩潰,或者其他的原因。該位也可以被用來拒絕一個無效的數(shù)據(jù)段,或者拒絕一個連接請求。一般而言,如果你得到的數(shù)據(jù)段設(shè)置了rst位,那說明你這一端有了問題。
tcphdr->psh 接收方在收到數(shù)據(jù)后應(yīng)立即請求將數(shù)據(jù)遞交給應(yīng)用程序,而不是將它緩沖起來直到整個緩沖區(qū)接收滿為止(這樣做的目的可能是為了效率的原因)
tcphdr->ack ack位被設(shè)置為1表示tcphdr->ack_seq是有效的。如果ack為0,則該數(shù)據(jù)段不包含確認(rèn)信息,所以,tcphdr->ack_seq域應(yīng)該被忽略。
tcphdr->urg 緊急指針有效
tcphdr->ece 用途暫時(shí)不明
tcphdr->cwr 用途暫時(shí)不明
內(nèi)核源代碼在函數(shù)tcp_transmit_skb()中建立tcp首部。
posted on 2008-11-21 10:48
水 閱讀(1566)
評論(0) 編輯 收藏 引用 所屬分類:
tcp/ip