文章目录
  1. 1. TCP/IP
  2. 2. TCP/UDP
    1. 2.1. TCP/UDP简介
    2. 2.2. 建立TCP连接(三次握手)
    3. 2.3. 关闭TCP连接(四次挥手)
    4. 2.4. TCP和UDP的区别

上一篇简单介绍了charles的主要功能。其实charles最大的功能就是抓http&https包,而http&https又是基于TCP的应用层协议。由此延伸,先大概的总结一TCP&UDP,希望能有所帮助~

TCP/IP

网络协议通常分不同层次进行开发,每一层分别负责不同的通信功能。一个协议族,比如TCP/IP,是一组不同层次上的多个协议的组合。TCP/IP通常被认为是一个四层协议系统,由下而上依次是:

  • 链路层:有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。

  • 网络层:有时也称作互联网层,处理分组在网络中的活动,例如分组的选路。在TCP/IP协议族中,网络层协议包括IP协议(网际协议),ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。

  • 运输层:主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。

  • 应用层:负责处理特定的应用程序细节。几乎各种不同的TCP/IP实现都会提供下面这些通用的应用程序:

    • Telnet远程登录。
    • FTP文件传输协议。
    • SMTP简单邮件传送协议。
    • SNMP简单网络管理协议。

TCP/UDP

TCP/UDP简介

TCP和UDP是两种最为著名的运输层协议,二者都使用IP作为网络层协议

  • TCP:使用不可靠的IP服务,但它却提供一种可靠的运输层服务。TCP提供一种面向连接的、可靠的字节流服务。面向连接意味着两个使用TCP的应用在彼此交换数据之前必须建立一个TCP连接。
    tcp首部

    • 序列号seq:4字节,标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
    • 确认号ack:4字节,指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
    • 确认ACK:1字节,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
    • 同步SYN接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
    • 终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
    • 注:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。
  • UDP:是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。UDP不提供可靠性,它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地。

建立TCP连接(三次握手)

  1. 客户端发送一个SYN段指明客户打算连接的服务器的端口以及初始序号,并进入SYN_SENT状态,等待服务器确认;SYN(Synchronize Sequence Numbers):同步序列编号。
  2. 服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时发回包含服务器的初始序号的SYN报文段(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
  3. 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器端进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
  • Q:那为什么需要三次握手呢?
    A:首先两次握手是最基本的。客服端在得到服务端的反馈后,才确定自己与服务端是可以连接上的。而第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。

    例如:客服端发送因为网络延迟等原因,直到连接释放的某个时间点才到达服务端,这是一个早就失效的报文,但服务端不知情仍然回应了客户端。如果只有两次握手,那么到这里连接就建立了,但是此时客户端并没有任何数据要发送,而服务端还在傻傻的等候佳音,造成很大的资源浪费。

关闭TCP连接(四次挥手)

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u。此时客户端进入FIN_WAIT_1状态。TCP规定,FIN报文即使不携带数据,也要消耗一个序号。
  2. 服务器端收到释放连接报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE_WAIT状态。客户端想服务器方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。
  3. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器进入LAST_ACK状态,等待客户端的确认。
  4. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是u+1,此时,客户端进入了TIME_WAIT状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。同时服务器只要收到客户端发出的确认,立即进入CLOSED状态。
  • Q:为什么连接的时候是三次握手,关闭的时候却是四次挥手?
    A:因为三次握手中,当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文,其中ACK报文是用来应答的,SYN报文是用来同步的。而终止连接需要经过4次握手是由TCP的半关闭(halfclose)造成的。既然一个TCP连接是全双工,因此每个方向必须单独地进行关闭。收到一个FIN只意味着在这一方向上没有数据流动。一个TCP连接在收到一个FIN后仍能发送数据,即服务端收到FIN之后很可能不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端你的FIN报文我收到了。等Server端所有报文发送完毕,才发送FIN报文,故不能一起发送。

  • Q:为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?
    A:网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段,所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会等待2MSL时间,如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

TCP和UDP的区别

  1. TCP面向连接;UDP是无连接的
  2. TCP提供可靠的服务,即,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
  3. TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
  4. 每个TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
  5. TCP首部开销20字节;UDP首部开销8字节
  6. TCP的逻辑通信信道是全双工的可靠信道;UDP则是不可靠信道
文章目录
  1. 1. TCP/IP
  2. 2. TCP/UDP
    1. 2.1. TCP/UDP简介
    2. 2.2. 建立TCP连接(三次握手)
    3. 2.3. 关闭TCP连接(四次挥手)
    4. 2.4. TCP和UDP的区别