Tcp/ip三次握手

来源:互联网 发布:jsp点击调用java方法 编辑:程序博客网 时间:2024/05/16 17:18
 TCP/IP三次握手过程 2010-01-23 21:27:06

分类: 系统运维

TCP 连接的建立和终止过程 
  TCP连接是面向连接的,所谓的面向连接就是,当计算机双向通信时必需先建立连接,然后才能进行数据的传输,最后还要拆除连接。而同在一个网络层的UDP传输,是面向非连接的传输,也不是可靠的。
 TCP建立连接需要三次握手的过程,而拆除连接需要四次握手的过程。
 TCP连接的建立:
  1.服务器必须准备好接受外来的连接,这通过调用socket,bind,和listen函数来完成,称为被动打开。
  2.客户通过调用connect进行主动打开,这引起客户TCP发送一个SYN(Synchronize)分节(表示同步 SYN=J),它告诉服务器客户将在连接中发送的数据的初始序列号,一般情况下SYN分节不携带数据,它只包含有一
个IP头部,一个TCP头部,可能还有TCP选项。这时客户端进入SYN_SEND状态,并等待服务器确认。
3. 服务器必须确认客户的SYN,同时自己也要发送一个SYN分节,它含有服务器将在同一个连接中发送的数据的初始序列号,服务器向客户发送一个SYN(SYn=K)和对客户的ACK(J+1)。也就是SYN+ACK包。这里服务器
进入SYN_RECV状态。
4 客户必须确认服务器的SYN。这里会向服务器发送确认包ACK(ack = K+1),此包发送完毕,客户端和服务器专进入ESTABLISHED状态。至此,三次握手完成,TCP连接建立。
  完成三次握手,客户端和服务器开始传输数据。在握手过程中,ACK里的确认号为发送这个 ACK的一方所期待的对方的下一个序列号。因为SYN只占一个字节的序列号空间,所以每一个SYN的ACK中的确认号都是相应的初始序列号加1,每一个FIN的ACK的确认号为FIN的序列号加1、
  在这过程中,还有一些重要的概念需要能明白。
SYN:同步标志
同步序列编号(Synchronize Sequence Numbers)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。所以如果你拒绝进来的syn包,它将终止其他计算机打开你计算机上的服务,但是并不会你终止你使用别的计算机的服务。

FIN:结束标志
带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。
RST:复位标志
复位标志有效。用于复位相应的TCP连接。
URG:紧急标志
紧急(The urgent pointer) 标志有效。紧急标志置位,
PSH:推标志
该标志置位时,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的
  
 未连接队列:
   在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN 包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器 进入ESTABLISHED状态。Backlog参数:表示未连接队列的最大容纳数目。
SYN-ACK重传次数 :
服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超 过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

注意,每次重传等待的时间不一定相同。
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

TCP选项:
   每一个SYN可以含有若干个TCP选项,通常使用的选项有:
MSS选项:TCP发送的SYN中,带有这个选项是通知对方它的最大分节大小MSS(maximum segment size),即它能接受的每个TCP分节中的最大数据量,可以使用TCP_MAXSEG套接口选项获取与设置这个TCP选项(Linux系统下)。
 窗口规模选项:TCP双方能够通知对方的最大窗口大小是65535,因为TCP头部相应的字段只占16位,这个选项指定TCP头部的广告窗口必须扩大(左移)的位数(0--14),因此所提供的最大窗口几乎是1G字节(65535*2的14次方)
时间戳选项:这个这项对高速连接是必要的,它可以防止失而复得的分组可能造成的数据损坏,也就是说是暂时的路由原因造成的迷途的分组,当路由稳定后,它们又会正常到达目的地,其前提是它们在此前尚未被路由主动丢弃。

TCP连接终止:
 TCP用三次握手建立一个连接,而终止一个连接则需要四次握手。
1. 某个应用进程首先调用close,我们称这一端执行主动关闭(active close),这一端的TCP于是发送一个FIN分节,表示数据发送完毕。
2. 接收到FIN的另一端执行被动关闭,这个FIN由TCP确认,它的接收也作为文件结束符,传递给接收方应用进程(放在已排队等候该应用进程接收的任何其他数据之后),因为FIN的接收意味着应用进程在相应连接上再也接收不到额外数据。
3. 一段时间后,接收到文件结束符的应用进程将调用close关闭它的套接口,这导致它的TCP也发送一个FIN、
4. 接收到这个FIN的源发送方TCP,对它进行确认。发送ACK、
 FIN占据1个字节的序列号空间,这与SYN相同,所以每个FIN的ACK确认号是这个 FIN的序列号加1.
在步骤2与步骤3之间可以有从执行被动关闭端到执行主动关闭端的数据流,这称为半关闭。不管是客户还是服务器都可以执行主动关闭。通常情况下是客户执行主动关闭。

注意:
四次握手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送. 注意在,由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记). 但在正常的TCP连接中RST包可以带ACK确认标记请注意RST包是可以不要收到方确认的
下面是一个简单的TCP连接的例子:其中涉及到了主要的数据包的变化。

握手阶段:
序号 方向    seq           ack
1  A->B 10000          0
2      B->A   20000   10000+1=10001
3     A->B   10001     20000+1=20001
解释:
1:A向B发起连接请求,以一个随机数初始化A的seq,这里假设为10000,此时ACK=0
2:B收到A的连接请求后,也以一个随机数初始化B的seq,这里假设为20000,意思是:你的请求我已收到,我这方的数据流就从这个数开始。B的ACK是A的seq加1,即10000+1=10001
3:A收到B的回复后,它的seq是它的上个请求的seq加1,即10000+1=10001,意思也是:你的回复我收到了,我这方的数据流就从这个数开始。A此时的ACK是B的seq加1,即20000+1=20001
数据传输阶段:
序号  方向    seq      ack    size
23          A->B           40000 70000 1514
24          B->A           70000 40000+1514-54=41460 54
25          A->B           41460 70000+54-54=70000 1514
26          B->A           70000 41460+1514-54=42920 54

解释:
23:B接收到A发来的seq=40000,ack=70000,size=1514的数据包
24:于是B向A也发一个数据包,告诉B,你的上个包我收到了。B的seq就以它收到的数据包的ACK填充,ACK是它收到的数据包的SEQ加上数据包的大小(不包括以太网协议头,IP头,TCP头),以证实B发过来的数据全收到了
25:A在收到B发过来的ack为41460的数据包时,一看到41460,正好是它的上个数据包的seq加上包的大小,就明白,上次发送的数据包已安全到达。于是它再发一个数据包给B。这个正在发送的数据包的seq也以它收到的数据包的ACK填充,ACK就以它收到的数据包的seq(70000)加上包的size(54)填充,即ack=70000+54-54(全是头长,没数据项)。
0 0
原创粉丝点击