计算机网络之TCP

运输层定义

1.前几个层实现了主机到主机的通信,但实际上计算机网络中进行通信的实体位于通信两端的主体中的进程
而运输层的任务就是为运行在不同端系统上的应用进程之间提供逻辑通信,所以运输层协议又称端到端协议

2.运输层向高层用户屏蔽了下面网络核心的细节,它使应用进程看起来好像是在 两个运输层实体之间有条端到端的逻辑通信信道
所以根据应用进程需求的不同,
运输层为应用层提供两种不同的运输协议:

  • TCP:
    面向连接的,可靠的协议流
    TCP为了能够提供可靠传输,实行‘顺序控制’或‘重发控制’机制。此外还具备‘流控制(流量控制)’、‘拥塞控制’、提供网络利用率等众多功能
  • UDP:
    无连接的,是不具有可靠性数据报协议,细微的处理会交给上层的应用去完成

运输层端口号

什么是运输层端口号:
首先运行在计算机上的进程使用进程标识符PID来标志,不同的操作系统使用不同格式的进程标识符,为了使不同操作系统应用进程之间能够通信,就需要使用统一的方法对应用进程进行标识,所以才有了端口号

端口号的作用:
TCP/IP体系的运输层使用端口号来区分应用层的不同进程

端口号的分类:
端口号使用16比特表示,取值范围0~65535

1.熟知端口号:FTP使用21/20, HTTP使用80,DNS使用53。
2.登记端口号:使用这类端口号必须在IANA按照规定的手续登记,以防止重复。例如: Microsoft RDP微软远程桌面使用的端口是3389.
3.短暂端口号: 留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。

端口号只具有本地意义,端口号只是为了标识本计算机应用进程的个进程,在因特网中,不同计算机中相同的端口号没有联系

运输层使用不同的端口号来区分主机上的应用进程

多路复用和多路分解

俗称为发送方的复用和接收方的分用
UDP和TCP最基本的任务是:将两个端系统间IP的交付服务 扩展为端系统上应用进程之间的交付服务

一个进程有一个或多个套接字,每个套接字有唯一的标识符。运输层并没有将数据交付给应用层,而是交付给中间的套接字。

  • 多路复用
    在发送端源主机中 使用不同的套接字中收集的数据块,并为每个数据块封装上首部信息从而生成报文段传递到网络层,多个套接字复用一个传输
    运输层多路复用的要求:
    套接字有唯一标识符。
    每个报文段有特殊的字段指示该报文段所要交付的套接字,这些用来标识的字段称为:源端口字段(source port number field)和目标端口字段(destination port number field)

  • 多路分解
    在接收端,运输层检查发来的报文段,通过发送端发来的首部信息,检查字段中的信息,标识出正确的套接字,进而将报文段定向到该套接字。将运输层报文段中的数据交付到正确的套接字的工作称为多路分解

TCP和UDP的区别:

UDP:用户数据报协议

UDP是一个简单的面向数据报的运输层协议,它是不可靠,无连接的

UDP面向数据报:
UDP只是数据报的搬运工,不会对报文进行任何拆分和拼接的工作
对应用层交付的数据直接打包进UDP报文段并立即将其传递给网络层
具体来说:
在发送端,应用层将数据传递给运输层的UDP 协议,UDP 只会给应用层报文加个UDP首部, 然后就传递给网络层
在接收端,网络层将数据传递给运输层,UDP 只去除IP 报文头就传递给应用层,不会任何拼接操作

UDP不提供可靠性:
1.它把应用程序传输的数据报发送出去,但是并不保证它们能否到达目的地
2.不使用流量控制和拥塞控制,在某些实时性要求高的场景用UDP

UDP无连接:
UDP不需要任何准备即可进行数据传输,也就是通信不需要建立和断开连接

UDP传输数据高效性:
分组首部开销小,每个 TCP 报文段都有 20 字节的首部开销,而 UDP 仅有 8 字节的开销,所以在传输数据报文时很高效

UDP的传输方式:UDP不止支持一 对一的传输方式,同样支持一对多, 多对多,多对一的方式,也就是说UDP提供了单播,多播,广播的功能

UDP报文段结构

在这里插入图片描述
UDP 首部包含了四个字段,每个字段由两个字节组成。

  • 端口号表示发送进程和接收进程。用于将应用数据分发给相应的进程。由于 IP 层已经把 IP数据报分配给TCP或UDP,所以UDP端口和TCP端口是相互独立的。
  • 长度字段指示了UDP报文段中的字节数(首部 + 数据)。
  • 校验和来检查该报文段是否出现了差错。

UDP 检验和
UDP 检验和提供了差错检测功能,是基于端到端原则实现的。但是 UDP 的检验和并不提供差错回复的能力。
这就是说,检验和用于确定当 UDP 报文段从源到达目的地移动时,其中的比特是否发生了改变。

发送方的 UDP 对报文段中的所有 16 比特字的和进行反码运算,计算出检验和。接收方接受到之后将所有16 比特字和检验和进行相加,如果和是1111111111111111,则没有差错,反之则出现差错。

如果发送端没有计算检验和而接收端检测到检验和有差错,那么 UDP数据报就要被悄悄地丢弃。不产生任何差错报文。

UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。

UDP丢包的优化方案

TCP:传输控制协议

TCP面向连接的可靠传输服务:
使用TCP协议的双方在传输之前必须使用‘三次握手’来建立TCP连接。TCP连接建立成功后才能进行数据传输。数据传输结束后,必须使用‘四报文挥手’来释放TCP连接,这里所谓的连接指的是逻辑连接关系,而不是物理连接

TCP连接提供的是全双工服务,基于TCP连接的两端,可以同时进行TCP报文段的发送和接收

使用流量控制和拥塞控制

TCP仅支持单播也就是一对一通信

TCP面向字节流的:
发送方的TCP:把应用进程交付下来的进程块,仅仅看做是一连串的、无结构的字节流。TCP并不知道这些待发送的字节流的含义。将他们编号存储在自己的发送缓存中,TCP根据发送策略,从发送缓存中提取一定数量的字节,构建TCP报文段并发送
接收方的TCP:一方面从所接收到的TCP报文段中取出数据载荷部分并存储在接收缓存中,一方面将接收缓存中的一些字节交付给应用进程

TCP是什么:

主要有两点:
面向连接的可靠传输服务:
1.(建立连接)使用TCP协议的双方 ,在传输之前,必须建立三次握手来建立TCP连接,TCP建立连接后才能传输数据,数据传输结束后必须使用四报文挥手来释放连接,
2.(可靠传输服务)除此之外,TCP还采用流量控制,拥塞控制来提供可靠传输服务
3.(怎么样的服务)建立逻辑连接的TCP提供的是全双工服务,对于TCP两端可以同时进行TCP报文段的接收或发送,但是TCP仅支持单播一对一通信

面向字节流的服务:(明确什么是字节流)
主要是发送方的发送机制问题,如果用户消息通过UDP协议传输时,操作系统不会对消息进行拆分,加上UDP头部就发送给网络层,所以发出去的UDP报文中的数据部分就是完整的用户消息。
但是用户消息(数据流)通过TCP协议传输时,会将应用进程的数据看作是无结构的字节流,发送方将数据排序存放在缓存区,TCP在发送数据时不会一次性发送,接收时会逐个接收数据,TCP会根据发送策略决定什么时候发送

为什么UDP没有粘包:

因为UDP是面向报文段发送的服务,UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。

为什么会发生TCP粘包、拆包

(首先解释什么是粘包拆包)
TCP是面向字节流的服务,没有边界。而操作系统在处理TCP是会通过缓存区来优化。
粘包问题:如果一次发送的数据量较小,没有达到缓存区大小,TCP会将多个请求合并为同一个请求发送,这就出现粘包问题
拆包问题:如果数据量太大,超过了缓存区大小,TCP则会将它拆分为多次发送

(为什么会发生这些情况)
粘包产生的原因:
TCP在建立连接之后,不断开的情况下会源源不断向服务器发数据流
第一种情况是:如果发送的数据包太小,会启用Nalge算法对较小的包进行合并然后发送,服务端在接收数据流时就区分不开哪些是客户端自己进行合并发送的
第二种情况是:当数据流已到达服务器端的缓存区,如果消息还没来得及取走,等下次取数据时可能会一次取多个的情况
拆包产生的原因:
拆包产生的原因很多,IP分片传输导致,或者是传输过程中出现丢失部分包,一个包被分成两次传输,在接收数据时分开接收,总之是一个数据包被分成多次接收的情况

粘包、拆包解决方法

粘包出现是因为不知道用户消息的边界在哪里
一般有三种分包方式:
固定长度的消息:
即固定消息长度,通过每个消息长度来区分,灵活性不高,并且有个小问题就是如果客户端第一个数据包数据长度封装的有错误,那么很可能就会导致后面接收到的所有数据包都解析出错
使用特殊字符作边界:
采用固定的字符作结尾符,在我们接收到数据包时,如果有结尾符代表需要把数据包拆来,如果没有等待下一个数据包出现,处理完整的数据包
自定义消息结构:
我们可以自定义一个消息结构,包括包头和数据,在包头里规定数据长度大小,解析包头知道长度大小来处理数据。当接收方接收到包头的大小(比如 4 个字节)后,就解析包头的内容,于是就可以知道数据的长度,然后接下来就继续读取数据,直到读满数据的长度,就可以组装成一个完整到用户消息来处理了。

TCP报文段结构

TCP为了实现可靠传输,TCP采用面向字节流的方式,TCP在发送数据时,是在发送缓存中取出一部分字节或者全部字节并添加一个TCP首部使之成为TCP报文段后进行发送
一个TCP报文段由首部数据载荷两部分组成
TCP的全部功能都体现在他首部中各字段的作用
在这里插入图片描述
源端口号(填写一个短暂端口号):用来标识发送该TCP报文段的应用进程

目的端口号(填写一个熟知端口号):用来标识接收该TCP报文段的应用进程

序号:指出TCP报文段数据载荷的第一个字节的序号
在这里插入图片描述
因为TCP将数据看成是一个无结构、有序的字节流
序号将一个TCP报文段的第一个字节标记,序列号的初始值并非为0,而是建立连接后由随机数生成,而后面的计算则是对每一个字节加一

序号的作用:
接收方可以去除重复的数据
接收方可以根据序号按序接收
可以标识发送出去的数据包中,哪些是已经被对方收到的

确认号
在发送端的数据到达接收主机时,接收主机会返回一个已收到消息的通知,这个消息叫做确认应答(ACK)
确认号表示:期望收到对方下一个接收到的数据载荷第一个字节的序号是多少,同时也是对之前收到的所有数据的确认
若确认号=n,则表明到序号n-1为止的所有数据都已正确接收,期望接收序号为n的数据

首部长度:占4位,用来指出TCP报文段的数据载荷的部分距离TCP首部有多远。这个字段实际上就是TCP报文段首部的长度。首部固定的字节为20,因此数据偏移字段的最小值为(0101)2.
保留字段:占6比特,为以后使用,目前应置为0。

TCP 有 6 个标志字段,用来说明报文段的性质:
UGR 紧急标志位:
用来实现紧急操作,当URG=1时表示紧急指针有效

ACK 确认标志位
ACK=1时【确认号字段】才有效,TCP规定除了最初发送SYN报文段以外,该位都必须置为1

PSH 推送标志位
用来实现推送操作,当PSH=1时,接收方的TCP收到PSH=1的报文段应该尽快上交应用进程,不用等缓存区满再上交

RST 复位标志位
用来复位TCP连接,RST=1时,表明TCP连接出现异常需要释放连接,重新建立连接,还可以用来拒绝一个非法的报文段或拒绝打开一个TCP连接

SYN 同步标志位:
在TCP连接建立时用来同步序号

FIN 终止标志位:
用来释放TCP连接,FIN=1时,表明是TCP连接释放报文段

紧急指针:
占16比特,以字节为单位,用来指明紧急数据的长度。
当发送有紧急数据的时候,可以插队到 发送缓存的最前面,然后封装成TCP报文段进行发送。紧急指针会指出本报文段数据载荷部分包含了多长的紧急数据,紧急数据之后是普通数据。
接收方收到URG为1的报文段的时候,,直接将紧急数据上交给应用进程,而不必在接收缓存中排队。

窗口字段:占16比特,指出发送本报文段的一方的接收窗口。窗口值作为接收方让发送方设置其发送窗口的依据。这个是以接收方的能力来控制发送的发送能力,称为流量控制。注意发送窗口的大小应该从接收窗口和拥塞窗口中取小点的一个。

校验和字段
占16比特
用来检验传输过程中是否出现了误码。在计算校验和的时候,要在TCP报文段的前面加上12字节的伪首部。

选项
占40个字节,增加选项可以增加TCP的功能。目前有以下选项:
最大报文段长度MSS选项:TCP报文段数据在和部分的最大长度。
窗口扩大选项:为了扩大窗口(提高吞吐率)
时间戳选项:用来计算往返时间RTT,
用于处理序号超范围的情况,又称为防止序号绕回PAWS。
选择确认选项:用来实现选择确认功能。

三次握手

三次握手其实就是建立TCP连接时,客户端和服务器端总共发送三个包,三次握手的主要作用是为了确认双方的接受能力和发送能力是否正常,指定自己的初始化序号为后面的可靠传输作准备。

刚开始客户端处于closed状态,服务器端处于Listen状态
第一次握手:
客户端会给服务器端发送一个SYN报文段,并指明客户端初始化序号ISN,表示想要和服务器端建立连接,此时客户端处于SYN_SENT状态
SYN=1,seq=x。SYN=1的报文段不能携带数据,但要消耗掉一个序号

第二次握手:
服务器端接收到SYN报文段后,会以自己的SYN报文段作为应答,并指明服务端的初始序号ISN,为了表示已经收到SYN报文段,服务器会将确认字段置为ISN+1,之后服务器发送SYNACK报文段,此时服务器处于SYN_RCVD状态
SYN=1,ACK=1,seq=y,ack=x+1

第三次握手:
客户端收到SYNACK报文段后,会给服务器端发送ACK报文段,表示自己已经收到。并同步自己的序号将初始序号+1,此时客户端处于ESTABLISHED状态,服务器端接收到ACK报文后也处于ESTABLISHED状态,此时连接已建立
第三次握手客户端可以携带数据发送给服务器端,将ACK=1,seq=x+1,ack=y+1
在这里插入图片描述

为什么是三次握手而不是两次握手

三次握手是为了双方都能收到数据,且确认双方都收到数据,少了第三次,服务端就没法确认客户端有没有收到数据包。这样,才符合TCP协议全双工的模式。

1.避免旧连接造成混乱和资源浪费
2.同步双方初始化序号

SYN洪泛攻击

SYN洪泛攻击是一种黑客攻击手段,利用TCP连接的缺陷。在二次握手之后,服务器端会进入SYN-RCVD状态,此时称为半连接状态,如果客户端迟迟没有发ACK报文来进行三次握手,服务器端将在(一分半钟)终止半连接状态并回收资源。而在这期间如果攻击者在短时间内伪造大量的IP地址,并向服务器端发送SYN报文段,此时服务器端将不断向客户端发送SYNACK报文段,并等待ACK报文段,因为是伪造的IP的地址原地址不存在,则服务器将不断重发直至超时,这些伪造的SYN报文段长时间占据未连接队列,导致正常的SYN包因为队列满而被丢弃,引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

DDOS 攻击是一大类攻击的总和,目的在于使用大量的请求,耗尽服务器的资源,导致停止服务或者实质下线。

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

netstat -n -p TCP | grep SYN_RECV

常见的防御 SYN 攻击的方法有如下几种:
SYN cookies技术
过滤网关防护
缩短超时时间
增加最大半连接数

四次挥手

为什么还要进行四次挥手才能关闭,这是因为TCP半关闭状态,所谓的半关闭,指的是TCP连接的一端已经关闭发送数据的能力还能接收对方发来的数据、

双方都可以主动发起挥手动作,刚开始双方都处于ESTABLISHED状态
假设客户端先发起关闭请求:
第一次挥手:
客户端会发生一个FIN报文段,进入FIN-WAIT-1状态,等待服务器端的确认

第二次挥手:
服务器端收到FIN报文段后,并向客户端发送ACK报文段,进入CLOSED-WAIT状态
客户端接收到ACK报文后,进入FIN-WAIT-2状态

第三次挥手:
等待服务器端处理完数据后,会给客户端发送FIN报文段,并进入LAST-ACK状态

第四次挥手:
客户端收到FIN报文后,会给服务器端发送ACK报文,并进入TIMEWAIT状态
服务器端收到ACK报文后进入CLOSED状态,至此服务器端关闭
客户端在经过2MSL时间后自动进入CLOSED状态,至此服务器端关闭
在这里插入图片描述

为什么需要四次挥手

因为服务器在发送完确认报文后,通常需要等待完成数据的发送和处理,才能关闭

为什么需要最后TIME_WAIT 状态

1.防止已失效的连接请求报文段出现在本连接中
最后的TIME_WAIT 状态可以使本连续内所有的报文段都从网络中消失,这样下一个新连接时就不会有旧连接的出现
2.保证双方可以正常关闭

TIME_WAIT 状态为什么是2MSL

MSL是最大生存时间,它是任何报文段在丢弃前的最大时间
客户端接收FIN和发送ACK刚好是2MSL的时间,如果服务器端没有接收到ACK就会重发FIN,如果超过了2MSL还没有接收到服务器发过来的FIN将断开连接

不等待2MSL会怎样

Websocket是什么,怎么实现Websocket全双工通信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值