计算机网络(一):TCP/UDP协议

一、tcp协议

传输控制协议TCP(Transmission Control Protocol)提供可靠的、面向连接的协议(eg:打电话)、传输效率低、全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
他的报文格式是:

  • 源端口(2字节):发送端应用程序的端口号,与源IP地址确定一个唯一地址
  • 目的端口(2字节):接收端计算机应用程序的端口号,与目的IP地址确定唯一的地址
  • 序号(4字节):TCP是面向字节流传输的,他为每一个字节编了一个序号,该报文段中序号为传输数据第一个字节的序号,例如:一个报文端的数据部分大小为100个字节,他的序号为400,那么下一次报文段的序号就为500
  • 确认号(4个字节):指明了下一个期待接收的字节序号,表明该序号之前的所有字节都正确接收到了,只有当ACK为1的时候确认号才有效。B已经收到编号为700的数据,那么它的确认号就是701。
  • 数据偏移/首部长度(4个字节): 用来表示TCP报文数据段的起始处和TCP报文起始处的距离,即TCP报文首部的长度,由于首部含有可选项,所以TCP报头长度是不确定的。
  • 保留:为了将来定义新的用途保留,现在一般都置为0
  • URG紧急控制位:与紧急指针配合使用,当URG为1的时候,就是通知系统这个报文段有紧急数据,需要优先传输。
  • ACK确认控制位:当他为1的时候,确认号字段才有效,TCP规定,在连接建立后,所有ACK都应该置为1
  • PSH推送控制位:当报文段的psh为1的时候,接收方接到该报文段,就立刻将他交付给接收应用进程,而不是等缓存已满的时候再交付。
  • RST复位控制位:当报文段的RST为1的时候,说明该TCP连接出现错误,必须释放连接,并重新建立连接。
  • SYN同步控制位:在连接建立时用来同步序列号,当SYN=1,ACK=0时说明这是一个连接请求报文段,如果对方同意建立连接则应该在响应的报文段中将SYN=1,ACK=1,表示接受请求
  • FIN终止控制位:用来释放连接,当FIN=1时表示此报文段发送方的数据已经发送完毕,并要求释放连接。
  • 窗口(2字节):用来告知另一端,发送报文这一端能接受的窗口大小。即允许对方发送的数据量以此控制发送方发送数据的速率,从而达到流量控制,窗口最大为216-1=65535
  • 校验和:用CRC来校验整个TCP报文段,包括tcp头,tcp数据,由发送端进行计算和存储,接收端进行校验,如果接收方发现校验和有差错,则TCP段会被直接丢弃
  • 紧急指针(2字节):标识紧急数据在报文段结束的位置
  • 选项(40字节):长度可变,最大长度40个字节。

二、UDP协议

用户数据报协议UDP(User Datagram Protocol)提供不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
他的报文格式是:

计算机网络(一):TCP/UDP协议_第1张图片

三、TCP的三次握手和四次挥手

3.1 三次握手

TCP提供可靠的连接服务,采用三次握手确认建立一个连接。

具体过程如图:

计算机网络(一):TCP/UDP协议_第2张图片 其中:
  • 第一次握手:主机A发送位码为syn=1, 为自己产生一个初始序号seq number=x的数据包到服务器,主机B由SYN=1知道,A要求建立联机;(SYN=1的报文不携带数据,但是要消耗一个序号)
  • 第二次握手:主机B收到请求后如果同意连接,想A发送确认。向A发送ack number=(主机A的seq+1),syn=1,ack=1,同时为自己产生一个初始序号seq=y的包
  • 第三次握手:主机A收到B的确认,向B给出确认。检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。(防止已经失效的连接请求报文突然又传到B,B与现在并没有发出连接请求的A建立了连接,但A没有数据要发送,白白浪费B的资源)
  • 完成三次握手,主机A与主机B开始传送数据。

3.2 四次挥手

TCP提供可靠的连接服务,采用四次握手确认断开一个连接

具体过程如图:

计算机网络(一):TCP/UDP协议_第3张图片

其中:

  • 第一次握手:客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  • 第二次握手:服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,A向B的方向就释放了,这时候处于半关闭状态,即A已经没有数据要发送了,但是C若发送数据,A依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    A收到B的确认请求后,此时,A就进入FIN-WAIT-2(终止等待2)状态,等待B发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  • 第三次握手:B将最后的数据发送完毕后,就向A发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,B很可能又发送了一些数据,假定此时的序列号为seq=w,此时,B就进入了LAST-ACK(最后确认)状态,等待A的确认。
    第四次握手:A收到B的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,A就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当A撤销相应的TCB(传输控制块)后,才进入CLOSED状态。
  • 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

3.3 三次握手和四次挥手的常见面试题

  • 建立连接要三次握手,两次不行吗?

主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

  • 断开连接要四次握手,三次不行吗?

关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

  • 为什么TCP建立连接要进行3次握手,而断开连接要进行4次?

这是由于TCP的半关闭造成的。
因为TCP连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时每个方向上都要单独进行关闭,这个单方向的关闭就叫半关闭。
关闭的方法是一方完成它的数据传输后,就发送一个FIN来向另一方通告将要终止这个方向的连接。当一端收到一个FIN,它必须通知应用层TCP连接已终止了这个方向的数据传送,发送FIN通常是应用层进行关闭的结果。两端都进行这样的操作,再加上四次握手中第三次握手要发送数据的一次,就是四次握手。

  • 为什么Time_Wait状态要有2个MSL

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL等待的时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

四、TCP和UDP协议的应用场景

当对网络通讯质量有要求的时候使用TCP协议,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。

TCP和UDP协议应用时需要注意:

  1. 多播的信息一定要用udp实现,因为tcp只支持一对一通信。
  2. 网络数据大多为短信息,适合用udp实现,因为udp是基于报文段的,如果信息量太大,会在链路层中被分片,影响传输效率。
  3. 重视速度性能甚于重完整性和安全性,那么适合于udp,比如多媒体应用,缺一两帧不影响用户体验,但是需要流媒体到达的速度快,因此比较适合用udp
    4.如果又要利用udp的快速响应优点,又想可靠传输,那么只能考上层应用自己制定规则了。
    常见的使用udp的例子:ICQ,QQ的聊天模块(聊天和视频用udp,文件传输用tcp)。这主要是从服务器的角度考虑。如果每一个QQ用户从一上线到下线的这段时间都是用tcp长连接,那么对服务器的负担很大;如果使用tcp短连接,那么频繁的连接与断开也会造成网络负担。使用udp可以避开这些麻烦。

采用TCP传输协议的MSN比采用UDP的QQ传输文件慢,但并不能说QQ的通信是不安全的,因为程序员可以手动对UDP的数据收发进行验证,比如发送方对每个数据包进行编号然后由接收方进行验证,即使是这样,UDP因为在底层协议的封装上没有采用类似TCP的“三次握手”而实现了TCP所无法达到的传输效率。

你可能感兴趣的:(计算机网络)