1TCP/IP协议族
TCP/IP 协议族分为以下几层:
应用层:
决定了向用户提供服务时通信的活动,比如FTP(File Transfer Protocol,文件传输)、DNS(Doman Name System,域名服务)、HTTP(超文本传输)
传输层:
提供处于网络连接中的两台计算机之间的数据传输,在传输层有两个性质不同的协议TCP(TransmissionControlProtocol,传输控制协议)和UDP(UserDataProtocol,用户数据报协议)。TCP与UDP的不同在于数据的传输是否为基于连接的,前者是基于连接的,UDP则是非连接的。
网络层:
用来梳理网络上流动的数据报。数据包是网络传输的最小单位。该层决定了在于对方计算机通信时,要从众多的传输路线中选择一条合适的路线【合适的一条路线是通过路由来确定的】,并把数据包传送给对方。在这层中,最重要的就是IP协议,通过ip地址找到通信网中的某台指定的服务器。
链路层:
用来处理连接网络的硬件部分,包括控制操作系统、硬件的设备驱动、网络适配器【网卡】等。硬件上的范凑均在链路层的作用范围之内。
利用TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则会往应用层往上走。
发送端在层与层之间传输数据时,每经过一层必定会被打上一个该层所属的首部信息,反之,接收端在层与层之间传输数据时,每经过一层都会把对应的首部消去。当请求http//hacker.jp/xss/Web页面时。TCP/IP协议族中各层协议的作用
2TCP传输机制
TCP用于在互联网上提供可靠的、端到端的字节流之间的通信。TCP提供的服务具有以下特征:
- 面向连接的传输,传输数据前需要先建立连接,数据传输后需要释放连接
- 端到端通信【指定端口间的进程通信】
- 高可靠性,在传输过程中,能确保传输数据的正确性,不出现丢失或乱序
- 采用字节流方式,即以字节为单位传输字节序列。如果待传输数据过大,会将其分段
- 全双工方式传输,信息的接收和发送是同时进行的
2.1 TCP报文结构
因为TCP能够应用于大数据的传输,所以需要将过长的数据流分段,TCP的段结构如下:
TCP源端口(Source Port):源计算机上的应用程序的端口号,占 16 位。
TCP目的端口(Destination Port):目标计算机的应用程序端口号,占 16 位。
TCP地址与IP地址不同,IP地址是字节地址,一个节点可以运行多个运用,TCP地址是节点上某个应用的地址,这种应用在计算机内部是进程。为了找到对应的进程,报文段中包含TCP源端口与TCP目的端口的信息
tcp的端口可以在0——65535范围内选择。小于256时,被定义为常用端口,比如FTP文件传输使用21、20端口,TELNET服务使用23端口,HTTP超文本传输默认使用80端口等
TCP序列号(Sequence Number):占 32 位。它表示本报文段所发送数据的第一个字节的编号。
tcp为每个连接建立了一个数据缓冲区,会对字节流中的每个字节进行编号,缓冲中的字节第一个位置的编号为0,后面的每个字节编号递增。当SYN标记不为1时,这是当前数据分段第一个字节的序列号;如果SYN的值是1时,这个字段的值就是初始序列值(ISN),用于对序列号进行同步。
TCP 确认号(Acknowledgment Number,ACK Number):占 32 位。它表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。其值=序列号+长度,即下一包起始序列号
TCP 首部长度(Header Length):数据偏移是指数据段中的“数据”部分起始处距离 TCP 数据段起始处的字节偏移量,占 4 位。其实这里的“数据偏移”也是在确定 TCP 数据段头部分的长度,告诉接收端的应用程序,数据从何处开始。
标志位字段【常用】
ACK:表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。
SYN:在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
FIN:标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。
2.2 TCP三次握手建立连接
- 客户端先向服务端发送SYN包(Socket状态从closed变成SYN-SEND)。
- 服务端收到SYN包后(Socket状态从LISTEN变成SYN-RECV),向客户端发送针对此SYN包的SYN/ACK包,以确认收到了这个SYN包。
- 客户端收到此SYN/ACK包后(Socket状态由SYN-RECV变成Established),再向服务器发送SYN/ACK包
在建立连接的过程中,客户端与服务端共发送了3个数据包,所以叫做三次握手建立连接。使用三次握手建立连接能够确认客户端与服务端都能传输信息,避免在不可靠的网络上传输导致的丢包或者数据包顺序错乱。
2.3 TCP四次握手关闭连接
客户端和服务端都能主动关闭连接,这里以客户端主动要求关闭连接为例:
- 客户端先向服务端发送FIN包,告知服务器需要关闭连接,等待服务器的确认(Socket状态从ESTABLISHED变成FIN-WAIT-1)。
- 服务端收到FIN包后,明确客户端需要关闭连接,发送ACK确认包,此时服务端进入CLOSE-WAIT状态,客户端变为FIN-WAIT-2状态。此时服务端还有部分数据待处理,如忙着数据的读写,所以还需要服务端向客户端通知服务端何时需要关闭连接。在此阶段,客户端与服务端任然能够交互数据
- 服务端工作完成后,此时也有关闭连接的意图,此时向客户端发送FIN包,服务端变为LAST-ACK,客户端变为FIN-WAIT-2状态
- 客户端向服务器发送一个ACK应答报文段,之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。
在关闭连接的过程中,客户端与服务端共发送了4个数据包,所以叫做四次握手关闭连接。客户端和服务器都可以主动关闭连接,只有率先请求关闭的一方才会进入TIME_WAIT(时间等待状态)。只有等待TIME-WAIT变为CLOSED状态之后TCP连接才能真正释放掉。
这里值得注意的是,TIME-WAIT到CLOSED通常存在着一定的延迟,该socket占用的端口号将一直无法释放。如果服务器TIME_WAIT状态过多,占满了所有端口资源,则会导致无法创建新的连接。此种状态在高并发下进行网络请求会出现,这里需要考虑到如何建立少的TCP连接,如使用HttpClient池。