第三章|tcp协议

TCP协议是TCP/IP协议族中另一个重要的协议。和ip协议相比,tcp协议更靠近应用层,因此在应用程序中具有更强的可操作性。
从四个方面分析tcp协议:tcp头部信息、tcp状态转移过程、tcp数据流、tcp数据流的控制。

tcp服务的特点

传输层协议主要有两个:tcp协议和udp协议。tcp相对udp特点是:面向连接、字节流、可靠传输。
使用tcp协议通信的双方必须先建立连接,然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源,以管理连接的状态和连接上数据的传输。tcp连接是全双工的,即双方的数据读写可以通过一个连接进行。完成数据交换之后,通信双方都必须断开连接以释放系统资源。
tcp协议的连接是一对一的。
字节流服务和数据报服务的区别。这种区别对应到实际编程中,则体现为通信双方是否必须执行相同次数的读写操作。

tcp固定头部结构

tcp头部结构

16位端口号:告知主机该报文段是来自哪里(源端口)以及传给那个上层协议或应用程序(目的端口)的。
32位序号:一次tcp通信(从tcp连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
32位确认号:用作对另一方发送来的tcp报文段的响应。
4位头部长度:标识该tcp头部有多少个32bit(4字节),因为4位最大能表示15.所以tcp头部最长是60字节。
6位标志位:详细参考手册。
16位窗口大小:是tcp流量控制的一个手段。窗口指的是接收通告的窗口。他告诉对方本端的tcp接收缓存区还能容纳多少字节的数据这样对方就可以控制发送数据的速度。
16位校验和:由发送端填充,接收端对tcp报文段执行CRC算法以校验tcp报文段在传输过程中是否损坏(tcp头部和数据部分)。是tcp可靠传输的一个重要保障。
16位紧急指针:是一个正的偏移量。他和序号字段的值相加表示最后一个紧急数据的下一个字节的序号。

使用tcpdump观察tcp连接的建立和关闭

sudo tcpdump -i ens33 -nt '(src 192.168.30.109 and dst 192.168.30.108) or (src 192.168.30.108 and dst 192.168.30.109)'
season@ubuntu:~$ telnet 192.168.30.109
Trying 192.168.30.109...
Connected to 192.168.30.109.
Escape character is '^]'.
Ubuntu 16.04.3 LTS
ubuntu login: 
telnet> quit
Connection closed.

抓如下报:

IP 192.168.30.108.59344 > 192.168.30.109.80: Flags [S], seq 592835856, win 29200, options [mss 1460,sackOK,TS val 382619106 ecr 0,nop,wscale 7], length 0
IP 192.168.30.109.80 > 192.168.30.108.59344: Flags [R.], seq 0, ack 592835857, win 0, length 0
IP 192.168.30.108.59346 > 192.168.30.109.80: Flags [S], seq 4029748011, win 29200, options [mss 1460,sackOK,TS val 382622437 ecr 0,nop,wscale 7], length 0
IP 192.168.30.109.80 > 192.168.30.108.59346: Flags [R.], seq 0, ack 4029748012, win 0, length 0
IP 192.168.30.108.46412 > 192.168.30.109.7: Flags [S], seq 3127718471, win 29200, options [mss 1460,sackOK,TS val 382623239 ecr 0,nop,wscale 7], length 0
IP 192.168.30.109.7 > 192.168.30.108.46412: Flags [S.], seq 3459342002, ack 3127718472, win 28960, options [mss 1460,sackOK,TS val 2097790564 ecr 382623239,nop,wscale 7], length 0
IP 192.168.30.108.46412 > 192.168.30.109.7: Flags [.], ack 1, win 229, options [nop,nop,TS val 382623239 ecr 2097790564], length 0
IP 192.168.30.108.46412 > 192.168.30.109.7: Flags [F.], seq 1, ack 1, win 229, options [nop,nop,TS val 382624459 ecr 2097790564], length 0
IP 192.168.30.109.7 > 192.168.30.108.46412: Flags [F.], seq 1, ack 2, win 227, options [nop,nop,TS val 2097791784 ecr 382624459], length 0

因为整个过程中并没有发生应用层的数据的交换,所以tcp报文段的数据部分的长度总是0.

半关闭状态:tcp连接是双全工的,所以他允许两个方向的数据传输被独立关闭。意思就是通信的一端可以发送结束报文段给对方,告诉他本端已经完成了数据的发送,但允许继续接收来自对方的数据,知道对方也发送结束报文段以关闭连接。tcp连接这种状态被称为半关闭。

TIME_WAIT 状态

客户端连接在收到服务器的结束报文段之后,并没有直接进入CLOSED状态。而是转移到TIME_WAIT状态。在这个状态客户端连接要等待一般长为2MSL(报文段最大生存时间,标准文档建议值是2min)的时间,才能完全关闭。
TIME_WAIT 状态存在的原因有两点:可靠地终止tcp连接。保证让迟来的tcp报文段有足够的时间被识别位丢弃。

season@ubuntu:~$ nc -p 12345 192.168.30.108 23
^C
season@ubuntu:~$ nc -p 12345 192.168.30.108 23
nc:bin failed :address already in use'^C
season@ubuntu:~$ net
netcat      netkit-ftp  netstat     networkctl  
season@ubuntu:~$ netstat -nat
激活Internet连接 (服务器和已建立连接的)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN     
tcp        0      0 192.168.30.108:12345    192.168.30.108:23       TIME_WAIT  
season@ubuntu:~$ netstat -nat
激活Internet连接 (服务器和已建立连接的)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN     

上述代码显示,客户端程序被中断后,连接进入TIME_WAIT状态,12345端口仍被占用,所以客户端重启失败。

复位报文段

产生复位报文段的3种情况

  • 访问不存在的端口
    在主机B上执行telnet命令登录A主机上一个不存在的端口54321,并用tcpdump抓取该过程中两台主机交换的tcp报文段。
season@ubuntu:~$ sudo tcpdump -nt -i ens33 port 54321

season@ubuntu:~$ telnet 192.168.30.108 54321
Trying 192.168.30.108...
telnet: Unable to connect to remote host: Connection refused

IP 192.168.30.109.35538 > 192.168.30.108.54321: Flags [S], seq 4136023844, win 29200, options [mss 1460,sackOK,TS val 2102882001 ecr 0,nop,wscale 7], length 0
IP 192.168.30.108.54321 > 192.168.30.109.35538: Flags [R.], seq 0, ack 4136023845, win 0, length 0

由此可见A主机针对B主机回应了一个复位报文段(tcpdump输出R标志)。复位报文段的接收通告窗口大小位0,所以可以预见:收到复位报文段的一端应该关闭连接或者重新连接,而不能回应这个复位报文段。

  • 异常终止连接
    正常终止的方式:数据交换完成之后,一方给另一方发送结束报文段。tcp提供了异常终止一个连接的方法,给对方发送一个复位报文段。一旦发送了复位报文段。发送端所有排队等待发送的数据都将被丢弃。
  • 处理半打开连接
    服务端(或客户端)关闭或者异常终止了连接,而对方没有接收到结束报文段(比如发生了网络故障),此时,客户端(或服务器)还维持着原来的连接。而服务器(或)客户端即使重启,也已经没有该连接的任何信息了。这种状态称为半打开状态。

tcp交互/成块数据流

tcp报文段所携带的应用程序数据按照长度分为两种:交互数据和成块数据。
交互数据仅包含很少的字节,使用交互数据的应用程序(或协议)对实时性要求高,比如telnet、ssh等。成块数据的长度则通常位tcp报文段允许的最大数据长度。使用成块数据的应用程序(或协议)对传输效率要求高,比如tcp。
成块数据流:当传输大量大块数据的时候,发送方会连续发送多个tcp报文段,接收方可以一次确认所有这些报文段。

  • 一个虚拟连接的建立是通过三次握手来实现的
  1. (B) --> [SYN] --> (A)
    假如服务器A和客户机B通讯. 当A要和B通信时,B首先向A发一个SYN (Synchronize) 标记的包,告诉A请求建立连接.
    注意: 一个 SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources). 认识到这点很重要,只有当A受到B发来的SYN包,才可建立连接,除此之外别无他法。因此,如果你
    的防火墙丢弃所有的发往外网接口的SYN包,那么你将不 能让外部任何主机主动建立连接。
  2. (B) <-- [SYN/ACK] <--(A)
    接着,A收到后会发一个对SYN包的确认包(SYN/ACK)回去,表示对第一个SYN包的确认,并继续握手操作.
    注意: SYN/ACK包是仅SYN 和 ACK 标记为1的包.
  3. (B) --> [ACK] --> (A)
    B收到SYN/ACK 包,B发一个确认包(ACK),通知A连接已建立。至此,三次握手完成,一个TCP连接完成
    Note: ACK包就是仅ACK 标记设为1的TCP包. 需要注意的是当三此握手完成、连接建立以后,TCP连接的每个包都会设置ACK位
  • 四次握手用来关闭已建立的TCP连接
  1. (B) --> ACK/FIN --> (A)
  2. (B) <-- ACK <-- (A)
  3. (B) <-- ACK/FIN <-- (A)
  4. (B) --> ACK --> (A)
    注意: 由于TCP连接是双向连接, 因此关闭连接需要在两个方向上做。ACK/FIN 包(ACK 和FIN 标记设为1)通常被认为是FIN(终结)包.然而, 由于连接还没有关闭, FIN包总是打上
    ACK标记. 没有ACK标记而仅有FIN标记的包不是合法的包,并且通常被认为是恶意的
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353