本文主要讲关于传输层的概念,关于端口号的详解,知名协议TCP/UDP协议的格式的认识以及关于TCP/UDP协议的详解,最重要的关于TCP协议在数据传输过程的三次握手和四次挥手的过程;
一.什么是传输层???
负责端与端之间的数据传输;
二.关于端口号:
1.端口号的概念:
端口号在计算机网络应用中用于网络设备之间的链接。在网络技术中,端口(Port)大致有两种意思:
一是物理意义上的端口,比如,集线器、交换机、路由器用于连接其他网络设备的接口,SC端口等等;二是逻辑意义上的端口,一般是指TCP/IP协议中的端口;本文主要讲关于TCP和IP协议的端口号;
2.端口功能:在主机上标识一个进程;是uint64_t类型的数据,范围是0~65535;但是0–1023不推荐使用,因为0–1023是知名端口号,HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的;1024 – 65535是操作系统动态分配的端口号;
客户端程序的端口号, 就是由操作系统从这个范围分配的
2.端口号的工作过程:
操作系统拿到网卡接收到的数据后,通过数据中的端口号知道数据放到哪个socket的缓冲区内;一个端口号只能被一个进程占用,但一个进程可以使用多个端口号;
3.TCP/IP协议中的五元组:一条网络上的数据包含的五条信息,分别为源IP,目的IP,源端口号,目的端口号,协议号;
在TCP和IP协议中通过五元组来标识一个通信;
4.关于一些知名的端口号:
ssh服务器, 使用22端口 ;
ftp服务器, 使用21端口 ;
telnet服务器, 使用23端口;
http服务器, 使用80端口;
https服务器, 使用443端口;
5.主机上网络状态的查看:netstat -anptu
n 拒绝显示别名,能显示数字的全部转化成数字;
l 仅列出有在 Listen (监听) 的服務状态;
p 显示建立相关链接的程序名;
t (tcp)仅显示tcp相关选项;
u (udp)仅显示udp相关选项;
a (all)显示所有选项,默认不显示LISTEN相关 ;
三.传输层的协议:UDP和TCP协议
1.UDP协议: 用户数据报协议
(1)关于UDP协议端格式:

UDP协议的主要作用是将网络数据流压缩成数据报的形式;一个典型的数据报就是一个二进制数据的传输单位;每一个数据报的前8个字节用来包含头信息,剩余的字节则用来包含具体的传输数据;
由上图可知:UDP的包头由4个域组成:分别为源端口号,目的端口号,数据报长度,校验和;其中每个域各占两个字节的长度;
关于四个域各自的功能:
源端口/目的端口号: 进行数据传输,确定数据应该在哪个进程中处理;
校验和: 用于校验目的地一组数据项的和,以十六进制为数制表示的形式;如果校验和的数值超过十六进制的FF, 就要求其补码作为校验和;
数据报长度: uint16_t;意味着UDP数据报最大长度是64K-8;若sendto给予的最大的数据大于64K-8,则会报错;因为UDP在传输层不会进行数据分段;若传输的数据大于64k,则就要在应用层将数据分割成一个个小段进行传输;UDP传输并不保证数据报的有序到达,意味着接收数据的一方有可能会乱序;因此也需要用户在应用层进行包序管理;UDP提供整条数据向应用层进行交付(不会出现半个数据,因为头部中有报文长度标识),也正是因为数据报长度在协议头中有标识,因此UDP不会产生粘包问题;
UDP协议使用端口号为不同的应用保留其各自的数据传输通道;
(2)UDP协议的特点:
无连接:知道对端的IP地址和端口号就直接进行传输,不需要进行连接;
不可靠:没有确认机制,没有重传机制;如果因为网络故障该段无法发送到对方,UDP协议层也不会向应用层返回任何错误信息;
面向数据报:数据整条收发,灵活性比较低,但不会造成粘包问题;
(3)关于UDP的缓冲区:
UDP没有真正意义上的发送缓冲区, 调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果 缓冲区满了, 再到达的UDP数据就会被丢弃;
(4)关于UDP的应用层协议:
NFS: 网络文件系统;
TFTP: 简单文件传输协议;
DHCP: 动态主机配置协议;
BOOTP: 启动协议(用于无盘设备启动) ;
DNS: 域名解析协议;
2.TCP协议: 传输控制协议;
(1)TCP协议段格式:


a.源端口号/目的端口号:表示数据从哪个进程来到哪个进程去,各占16位;一个端口与主机的IP地址就可以完整地标识一个端点,也就是构成套接字(Socket);
b.序号: TCP数据段中的“数据”部分(不包含“数据段头”部分)的第一个字节的编号,占32位;在一个TCP连接中,传送的数据字节流的每一个数据字节都要按顺序进行编号,在“数据段头”中标识的只是每个数据段的第一个数据字节的编号。整个要传送的字节流的起始序号必须在连接建立时设置。例如,一个数据段的“序号”字段值是101,而该数字段中共有100个字节,表明本数据段的最后一个字节的编号是200。这样一来,下一个数据段的“序号”字段值应该是201,而不是102;
c.确认号: 确认号指期望接收到对方下一个数据段中“数据”部分的第一个字节序号,占32位;“确认号”不是代表已经正确接收到的最后一个字节的序号。例如,主机B已收到主机A发来的一个数据段,其序号值是101,而该数据段的长度是100字节。这表明主机B已收到主机A前200个字节,下一个期望要收到的数据段的第一个字节的序号应该是201,于是主机B在给主机A发送确认数据段时要把“确认号”设置为201;
d.数据偏移(4位TCP报头长度): 表示该TCP头部有多少个4字节数据,确定TCP数据段头部分的长度(偏移量是以32位(即4字节)为单位来计算的,而不是以单个字节来计算的);因为4个比特位可以表示的最大数为15,所以数据偏移量最大为60字节,这也是TCP数据段头部分的最大长度;所以TCP头部大长度是15 * 4 = 60;
e.6位标志位:
URG: 紧急指针是否有效;
ACK: 确认控制位,表示确认号是否有效;
PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走,置0时没有这个要求,则先缓存起来;
RST: 用于重置,释放一个已经混乱的传输连接,对方要求重新建立连接,我们把携带RST标识的称为复位报文段;
SYN: 用来在传输连接建立时同步传输连接序号;当SYN位置1时,表示这是一个连接请求或连接确认报文;当SYN=1,而ACK=0时,表明这是一个连接请求数据段;如果对方同意建立连接,则对方会返回一个SYN=1、ACK=1的确认;我们把携带SYN标识的称为同步报文段;
FIN: 用于释放一个传输连接;当FIN位置1时,表示数据已经全部传输完成,发送端没有数据要传输了,要求释放当前信号,但是接收端仍然可以继续接受还没有接受完的数据;在正常传输时,该位置0;我们称携带FIN标识的为结束报文段 ;
f.16位窗口大小: 指发送此TCP数据段的主机上用来存储传入数据段的窗口大小;即发送者当前还可以接受的最大字节数;“窗口大小”字段的值告诉接受本数据段的主机,从本数据段中所设置的“确认号”值算起,本端目前允许对端发送的字节数,是作为让对方设置其发送窗口大小的依据;
g.16位校验和: 检验和是对“数据段头”、“数据”、和“伪头部”这三部分进行校验,占16位;
h.16位紧急指针: 发送端填充, CRC校验;接收端校验不通过, 则认为数据有问题,此处的检验和不光包含TCP首部, 也包含TCP数据部分;
i.40字节头部选项: 字段是可选的,并且长度可变;当没有使用该字段时,TCP头部的长度是20字节;它可以包括窗口缩放选项,MSS(最大数据段大小),SACK(选择性确认)选项,时间戳(Timestamp)选项等;
(2)TCP协议特点及面向连接中的连接管理:
TCP协议特点:面向连接,可靠传输,面向字节流;
(3)TCP的三次握手和四次挥手:(面向连接中的连接管理)
我们知道在TCP面向连接的连接管理过程中服务端和客户端有各自的实现功能;
关于客户端的功能实现步骤:
1.创建套接字socket;
2.为套接字绑定地址信息bind;
3.接收数据‘’
4.发送数据;
5.关闭套接字;
关于服务端的功能实现步骤:
1.创建套接字socket;
2.绑定地址信息bind;
3.发送数据;
4.接收数据;
5.关闭套接字;
关于面向连接管理的过程:------三次握手和四次挥手;
如下图所示:

TCP的三次握手过程:
服务端先运行起来进行套接字的创建以及端口地址的绑定,开启监听状态–Listen;此时客户端需要向服务端发送一组信息,先进行套接字的创建,端口地址的绑定;**
(1)客户端先向服务端发起SYN连接请求(connect发起SYN连接请求),进入SYN_SENT状态;
(2)服务端创建新的socket,新建socket会向客户端发送ACK+SYN请求,告诉客户端服务端此时在线,由于在此过程中会出现网络等一系列问题,所以需要再次判断客户端此时是否还在线;
(3)当客户端接收到SYN+ACK信号后说明服务端在线,并且再次给服务端发送ACK信号,服务端接收到ACK信号;此时客户端和服务端已经连接成功;此时进入就绪状态ESTABLISHED,说明已经可以收发数据了;**
TCP的四次挥手过程:
经过多轮回复后,此时要断开连接,关闭任意一方都可以;**
(1)客户端发起一个close()就会向服务端发送一个FIN包,此时客户端处于FIN_WAIT_1状态;
(2)服务端接收到FIN包后处于CLOSE_WAIT状态,并且向客户端发送ACK信号;当客户端接收到ACK信号后处于FIN_WAIT_2状态;
(3)服务端给客户端发送FIN包,此时服务端的状态为LAST_ACK,最后一次发送请求(伴随着close());(4)此时客户端最后一次对服务端发送ACK信号并进入TIME_WAIT(2个WSL时间)等待时间;服务端接收到后直接关闭连接CLOSED,客户端等待两个MSL时间后关闭连接CLOSED;**
实例化:男女朋友分手案例:(更容易理解TCP的三次握手和四次挥手)

(4)关于TIME_WAIT状态的理解:
TIME_WAIT状态:指系统在等待客户端的响应的状态;
问题:如果没有TIME_WAIT的等待会怎么样?????
没有TIME_WAIT的等待会导致最后一个ACK信号的丢失;
被动方关闭方重新发送FIN包,没有等待直接关闭;若直接启动的客户端有使用相同的端口信息,就有可能收到FIN包,对新连接造成影响;若新客户端使用相同的客户端口信息,向服务端发送SYN请求,但是服务端没有收到最后一个ACK信号处于LAST_ACK 状态,收到SYN信号后判定状态错误,回复RST报文重置连接,也对新连接造成影响;
因此为了避免这种情况的出现:主动关闭方发送最后一个ACK信号之后需要等待两个MSL时间:主要作用为(1)处理若ACK丢失,导致对端重传的FIN包;
(2)等待网络中所有双方延迟的报文消失在网络中,不会对后续造成影响;
(5)面试题:
1.为什么TCP握手是三次,挥手是四次???
关于三次握手:主要目的是为了保证连接是双工,真正实现客户端与服务端之间的沟通正常;为了保证服务端能接收到客户端的信息并能做出正确的应答而实现一次握手;为了保证客户端能接收到服务端的信息并能做出正确的应答而实现两次握手;
关于四次挥手:因为是双方彼此都建立了连接,因此双方都要释放自己的连接,A向B发出一个释放连接请求,他要释放链接表明不再向B发送数据了,此时B收到了A发送的释放链接请求之后,给A发送一个确认,A不能再向B发送数据了,它处于FIN-WAIT-2的状态,但是此时B还可以向A进行数据的传送。此时B向A 发送一个断开连接的请求,A收到之后给B发送一个确认。此时B关闭连接,A也关闭连接------需要考虑半关闭状态;
2.若三次握手的时候第三次握手失败,服务器会如何处理???
tcp建立连接三次握手,主动方发送请求syn,server接收到信息,返回带有数据包的信息syn_sent,然后接收到信息的一方再发送确认信息ACK给server,第三次握手失败(超时)时,服务器并不会重传ack报文,server会发送RTS报文段并主动关闭至closed,以防止syn洪泛攻击;
3.什么是SYN泛洪攻击????
当第三次握手没有发送确认信息时,等待一段时间后,主机就会断开之前的半开连接并回收资源,这为DOS攻击埋下隐患;当主动方主动发送大量的syn数据包,但并不做出第三次握手响应,server就会为这些syn包分配资源(但并没有使用),就会使server占用大量内存,使server连接环境耗尽,这就是SYN泛洪攻击;
4.若服务器出现了大量的TIME_WAIT连接时,是什么原因造成的??
我们知道一般情况下由于主动关闭TCP连接的一方才会进入TIME_WAIT状态;一般情况服务器端不会出现TIME_WAIT状态,因为大多数情况都是客户端主动发起连接并主动关闭连接;但是某些服务如pop/smtp、ftp却是服务端收到客户端的QUIT命令后主动关闭连接,这就造成这类服务器上容易出现大量的TIME_WAIT状态的连接,而且并发量越大处于此种状态的连接越多;此外,对于被动关闭连接的服务在主动关闭客户端非法请求或清理长时间不活动的连接时(这种情况很可能是客户端程序忘记关闭连接)也会出现TIME_WAIT的状态;
3134

被折叠的 条评论
为什么被折叠?



