TCP和UDP

TCP和UDP是传输层两个重要的协议。HTTP协议基于TCP;DHCP协议基于UDP。

UDP

UDP包头在这里插入图片描述

UDP特点:

  1. 沟通简单,它相信网络是可以送达,不会被丢弃的;
  2. 轻信他人,不会建立连接,谁都可以给它传数据,它也可以给任何人传数据,甚至可以同时传给多个人数据。
  3. 不懂得随机应变,它不会根据网络的情况进行发包的拥塞控制,无论网络丢包成什么样子都一如既往。

UDP应用场景:

  1. 需要资源少,在网络情况比较好的内网,或者对丢包不敏感的应用。
  2. 不需要一对一沟通,建立连接而是可以广播的应用。UDP的不面向连接的功能使得可以承载广播或者多播的协议。
  3. 需要处理速度快,时延低,可以容忍少数丢包,但是要求即使网络拥塞也毫不退缩,一往无前的情况。

TCP

TCP是一种面向连接的、可靠的、基于字节流的通信协议。
IP协议是一种网络层协议,它规定每个互联网上的计算机都有一个唯一的IP地址,这样数据包就可以通过路由器的转发到达指定的计算机,但是IP并不保证数据传输的可靠性。
在TCP报文的报头中,有几个标志字段:

  1. SYN:同步连接序号,TCP SYN报文就是把这个标志设置为1,来请求建立连接;
  2. ACK:请求/应答状态。0为请求,1为应答;
  3. FIN:结束连线。0是结束连线请求,FIN为1表示结束连线;
  4. RST:连线复位,首先断开连接,然后重建;

TCP包头

在这里插入图片描述### TCP三次握手:
TCP的连接建立,常被称为“三次握手”。

A: 你好,我是 A
B:你好 A,我是 B
A:你好 B

以上过程也常被称为“请求 -> 应答 -> 应答之应答”,三次握手除了双方建立连接外,主要还是要沟通过TCP包的序号问题。
【补充】
如果A连接后就是不发数据,我们在程序设计时可以要求开启keepalive机制,即使没有真实的数据包也有探活包。并且作为服务端B的程序设计者,对于A长时间不发包这种情况可以主动关闭,空出资源给其他客户端用。
过程:
在这里插入图片描述

  1. 开始时客户端和服务端都处于closed状态,先是服务端主动监听某个端口,处于listen状态。然后客户端发起连接SYN,之后处于SYN-SENT状态。
  2. 服务端收到发起的连接,返回SYN(同步作用),并且ACK(应答作用)客户端的SYN,之后处于SYN-RCVD状态。
  3. 客户端收到服务端发送的SYN和ACK后,发送ACK的ACK,之后处于established状态,因为它一发一收成功了。
  4. 服务端收到ACK的ACK之后,处于established状态,因为它一发一收也成功了。

【状态解释】

closed       表示初始状态
listen       表示服务器端的某个socket处于监听状态,可以接受连接
SYN-SENT     表示客户端已经发送SYN报文
SYN-RCVD     表示服务端接收到了SYN报文
established  表示已建立连接

TCP四次挥手

A: B,我不想玩了。
B: 你不想玩了啊,我知道了。(此时只是A不再发数据,B还是可以发送数据的,A可以选择不接收,也可以选择再接收一次,然后等待B也关闭,称为半关闭状态)
B: A,我也不玩了,拜拜。
A: 好的,拜拜。(此时整个连接关闭)

过程:
在这里插入图片描述

  1. 客户端发送数据完毕后发送FIN,提出断开连接,就进入FIN_WAIT_1状态,服务端接收到FIN包后对客户端做出回应,发送ACK,进入CLOSED_WAIT状态。
  2. 客户端收到服务端的ACK包后就进入FIN_WAIT_2状态,此时如果服务端直接跑路的话,客户端将永远留在这个状态。
  3. 等服务器的应用程序做好关闭准备时,服务端给客户端发送FIN包,请求关闭连接,客户端收到以后,从FIN_WAIT_2状态结束,并给服务端发送确认包,但是客户端还不能退下,还要确保服务端收到了。TCP协议要求它等待一段时间TIME_WAIT,这个时间足够长。当然如果服务端超过时间依然没有收到客户端发确认包,那它依然还会重新发,此时如果A已经跑路,就会直接发送RST,服务端收到后就知道A已经跑路了。

【补充】
TIME_WAIT为2MSL:MSL为报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文会被丢弃。协议规定MSL为2min。

TIME_WAIT存在的意义:

  1. 确认被关闭端收到关闭端的ACK包,如果没有收到,被关闭端会重新发送。
  2. 保证无用报文消逝,不会影响下次连接。

TCP连接和断开状态图

在这里插入图片描述

Socket

Socket是介于应用层和传输层之间,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
客户端和服务端进行通信之前首先要建立一个Socket。Socket是端对端通信,所以往往意识不到中间经过多少局域网,多少路由器,因而能设置的参数也就是网络层和传输层的。在网络层需要指定到底是IPv6还是IPv4,传输层需要指定到底是TCP还是UDP。套接字必须包含连接使用的协议(TCP/UDP),本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:服务器端套接字处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:当服务器端套接字监听到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。
然后服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

1. 基于TCP协议的Socket程序函数调用过程
TCP服务端先监听一个端口,一般是调用bind函数,给这个Socket赋予一个IP地址和端口。服务端有了IP和端口号就可以调用listen函数进行监听,这个时候客户端就可以发起连接了。接下来服务端调用accept阻塞,等待客户端连接,如果客户端通过connect函数发起连接,现在参数中指明要连接的IP地址和端口号,然后三次握手,内核给客户端分配一个临时的端口。一旦连接,服务端的accept就会返回已连接socket。
【补充】

  1. 在内核中,为每个Socket维护两个队列,一个是已经建立连接的队列,处于established状态;一个是还没有完全建立连接的队列,处于syn_rcvd状态。
  2. 监听Socket和真正用来传数据的Socket是两个,一个叫监听Socket,一个叫已连接Socket。
    在这里插入图片描述
    2. 基于UDP协议的Socket程序函数调用过程
    UDP是没有连接的,所以不需要三次握手,也就不需要调用listen和connect,但是UDP的交互仍然需要IP和端口号,因此也需要bind。UDP是没有维护连接状态的,所以不需要每对连接建立一组Socket,而是只有一个Socket,就能和多个客户端通信。
    在这里插入图片描述

疑问

一. TCP为什么是三次握手,两次可以吗?
采用三次握手是为了防止失效的连接请求又突然传到服务端,比如第一次客户端向服务端发出请求,没有收到应答就重新发送请求,这一次收到应答了就建立了连接,但是第一次的请求因为网络延时也到达了服务端,服务端以为客户端又建立连接就又做出了应答等待客户端发数据过来,这样就造成资源浪费。
二. 为什么建立连接是三次握手,断开连接是四次挥手?
因为在建立连接时,服务端的listen状态下的socket接收到SYN包后,它把ACK和SYN放在一个报文里发送,但是断开连接时,收到对方的FIN时仅仅代表对方可以断开连接了,但是自己未必所有数据都发送完毕了,所以不会立马关闭socket,而是会先发送ACK包确认已收到对方断开请求,然后等自己做好准备后再发送FIN包请求关闭连接。
三. TCP为什么是四次挥手?
因为TCP的连接是全双工的,因此每个方向必须单独进行关闭,两次挥手只能说明一方没有数据要传输,因此处于半闭合状态,四次挥手才真正的关闭。

TCP和UDP的区别

  1. TCP是面向连接的;UDP是面向无连接的。
    【补充】
    在互通之前,面向连接的协议会先建立连接,比如TCP会三次握手,而UDP不会。所谓建立连接就是为了在客户端和服务端维护连接而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性。
  2. TCP提供可靠交付,通过TCP连接传输的数据无差错、不丢失、不重复并按序到达;但是UDP不保证不丢失,不保证按顺序到达。
  3. TCP是面向字节流的;UDP是基于数据报的,一个个地发,一个个地收。
  4. TCP有拥塞控制,会根据情况调整自己的行为,比如发包快慢;UDP是让发就一直发。
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读