3.Linux 高性能服务器编程 --- TCP 协议详解

3.TCP 协议详解
	URG : 表示紧急指针是否有效
	ACK : 表示确认号是否有效
	PSH : 表示接收端应用程序应该立即从 tcp 接收缓冲区读走数据,为接收后续数据腾出空间
	RST : 表示要求对方重新建立连接,我们称携带 RST 标志的 tcp 报文段为 复位报文段
	SYN : 表示请求建立一个连接,我们称携带 SYN 标志的 tcp 报文段为同步报文段
	FIN : 表示通知对方本端要关闭连接了。我们称携带 FIN 标志的 tcp 报文段为结束报文段

	半关闭状态:
		tcp 连接是全双工的,所以它允许两个方向的数据传输被独立关闭。
		服务器和客户端应用程序判断对方是否已经关闭连接的方法是:read 系统调用返回0.

	孤儿连接:
		客户端执行半关闭后,未等待服务器关闭连接就强行退出了。此时客户端连接由内核来接管,可称之为孤儿连接。

	time_wait 状态:
		在这个状态,客户端连接要等待一段长为 2MSL(Maximum Segment Life,报文段最大生存时间),才能完全关闭。
		MSL 是 tcp 报文段在网络中农的最大生存时间,标准建议值是 2min.
		time_wait 状态存在的原因有2个:
			1.可靠的终止 tcp 连接
			2.保证让迟来的 tcp 报文段有足够的时间被识别并丢弃。

		第一个原因很好理解,客户端需要停留在某个状态以处理重复收到的结束报文段(即向服务器发送确认报文段),否则客户端将以复位报文段来回应
	  服务器,服务器以为是个错误。

		在 Linux 系统上,一个 tcp 端口不能被同时打开多次(2次以上)。当一个 tcp 连接处于 time_wait 状态时,我们将无法使用该连接
      占用着的端口来建立一个新连接。反过来思考,如果不存在 time_wait 状态,则应用程序能够立即建立一个和刚刚关闭的连接相似的连接(这里
      说的相似,是指它们具有相同的 ip 地址和端口号)。这个新的,和原来相似的连接被称为原来连接的化身,新的化身可能收到属于原来连接的,携带
      应用程序数据的 tcp 报文段(迟到的报文段),这显然是不应该发生的。这就是 time_wait 状态存在的第二个原因。

        另外,因为 tcp 报文段的最大生存时间是 MSL,所以坚持 2MSL 时间的 time_wait状态能够确保网络上2个传输方向上尚未被接收到的,迟到的
      tcp 报文段都消失(被中转路由器丢弃)。因此,一个连接的新的化身可以在 2MSL时间之后安全的建立,而绝对不会接收到属于原来连接的应用程序,这就是
      time_wait 状态要持续 2MSL 时间的原因。

        有时候我们希望避免 time_wait 状态,因为当程序退出之后,我们希望能够立即重启它。但由于处在 time_wait 状态的连接还占用着端口,所有程序无法启动。
        但如果是服务器主动关闭连接后异常终止,则因为它总是使用一个知名服务端口号,所以连接的 time_wait 状态将导致它不能立即重启。不过,我们可以通过socket
      选项 SO_REUSEADDR 来强制进程立即使用处于 time_wait 状态的连接占用的端口。 

    复位报文段:
    	在某些特殊情况下,tcp 连接的一端会向另外一段发送 RST 标志的报文段,即复位报文段,以通知对方关闭连接或重建连接。
    	1.访问不存在的端口
    		复位报文段的接收通告窗口大小为0,所以可以预见:收到复位报文段的一端应该关闭连接或者重新连接,而不能回应这个复位报文段。
    		实际上,当客户端程序向服务器的某个端口发起连接,而该端口仍被处于 time_wait 状态的连接所占用,客户端程序也将收到复位报文段。

    	2.异常终止连接
    		tcp 提供了异常终止一个连接的方法,即给对方发送一个复位报文段。一旦发送了复位报文段,发送端所有的排队等待发送的数据都将被丢弃。

    	3.处理半打开连接
    		服务器(或者客户端)关闭后者异常终止了链接,而对方没有接收到结束报文段,此时,客户端(或服务器)还维持着原来的连接,而服务器(或客户端)即使重启了,
    	  也已经没有该连接的任何信息了。我们将这种状态称为半打开状态,处于这种状态的连接称为半打开连接。如果客户端(或服务器)往处于半打开状态的连接写入数据,
    	  则对方将回应一个复位报文段。

    带外数据:
    	有些传输层协议具有带外(out of band,OOB)数据的概念,用于迅速通知对方本端发生的重要事情。因此,带外数据比普通数据(也称带内数据)有更高的优先级,它应该
      总是立即被发送,而不论发送缓冲区中是否有排队等待发送的普通数据。带外数据的传输可以使用一条独立的传输层连接,也可以映射到传输普通数据的连接中。
        udp 没有实现带外数据传输,tcp也没有真正的带外数据。不过 tcp 利用其头部中的紧急指针标志和紧急指针两个字段,给应用程序提供了一种紧急方式。

        假设一个进程已经往某个 tcp 连接的发送缓冲区写入了 N 个字节的普通数据,并等待发送。在数据被发送之前,该进程又向这个链接写入了3个字节的带外数据'abc'。此时,
      待发送的tcp 报文段的头部被设置 URG 标志,并且紧急指针被设置为指向最后一个带外数据的下一个字节。

    超时重传:
    	tcp 服务必须能够重传超时时间内未收到的确认的 tcp 报文段。为此,tcp 模块为每个tcp报文段都维护一个重传定时器,该定时器在 tcp 报文段第一次被发送时启动。如果
      超时时间内未收到接收方的应答,tcp 模块将重传 tcp 报文段并重置定时器。至于下次重传的超时时间如何选择,以及最多执行多少次重传,就是 tcp 的重传策略了。

    拥塞控制:
    	慢启动
    	拥塞避免
    	快重传
    	快恢复

3.1 TCP 服务特点

 

3.2 TCP 头部结构

 

3.2.3 使用 tcpdump 观察 TCP 头

 

3.3 TCP 连接的建立与关闭

 

3.3.2 半关闭状态

 

3.3.3 连接超时

 

 

3.4 TCP 状态转移

 

3.4.2 TIME_WAIT 状态

 

3.5 复位的报文段

 

3.6 TCP 交互数据流

 

3.7 TCP 成块数据流

 

3.8 带外数据

 

3.9 TCP 超时重传

 

 

3.10 拥塞控制

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值