网络模型和TCP协议

目录

1、网络模型

2、TCP

2.1、TCP/IP模型

2.2、TCP连接

3、HTTP应用


1、网络模型

从上面的表格中可以看到,HTTP是应用层协议,TCP是运输层协议,根本不在一个维度上。

2、TCP

2.1、TCP/IP模型

 

2.2、TCP连接

TCP建立的连接是可靠的,只要不主动断开就一直存在,且传输的数据是有序的,可靠的,不丢失的,不重复的。

数据传输过程:

1、连接建立(三次握手)

主机A的TCP向主机B的TCP发送连接请求报文段,报文段中包含SYN=1,同时选择一个序号 x,表明在后面传送数据时的第一个数据字节的序号是 x+1

主机B收到连接请求报文段后,如果同意连接,发送确认报文段,在确认报文段中,把SYN和ACK都设为1,确认号ACK=x+1(告诉主机A传送数据时序号从x+1开始),同时也给自己选一个序号 y

主机A收到确认报文后,也要给B发送确认报文段,告诉主机B,ACK设为1(确认收到消息),确认号为 y+1 ,自己的需要是 x+1 

2、传输数据

TCP连接,应用程序不断的把数据写入到TCP缓存中(可以理解为byte数组),TCP 从缓存中取出一定量的数据,组成TCP报文段(segment)逐个传送给IP层。

接收端从IP层收到TCP报文段后,先存入接收端缓存中,然后接收端的应用进程从缓存中将数据块逐个读取。接收端每收到一部分数据,就会向发送端发送序号(我已经收到了第500个字节的数据),发送端会根据这个序号,发送序号后的数据。

发送报文示意图:

这种情况,就会产生TCP的粘包拆包问题。应用程序发送了10条数据,依次写到缓存中。这些数据包装成的报文段可能是1个,也可能是5个。接收端应用程序从缓存中获取的数据,不知道怎么区分这10条数据。

示例:发送端发送的数据,10次hello。 

hellohellohellohellohellohellohellohellohello

接收端收到的消息可能是 :

hellohellohel

lohellohell

ohellohell

ohell

ohello

解决这个问题的方法就是自定义发送接收数据的协议。比如在hello前面再加一个数字,标识发送的数据长度。

5hello5hello5hello5hello5hello5hello5hello5hello5hello

接收端根据协议,先读数字,得到5,然后读后面的5个字节。如果数据不够5个字节,等待。下次继续读。

使用netty中的过程中TCP粘包拆包问题就是这么解决的。关键的解码器 ReplayingDecoder

基本原理:

使用了特殊的ByteBuf,叫做ReplayingDecoderByteBuf,扩展了ByteBuf 重写了ByteBuf的readXxx()等方法,会先检查可读字节长度,一旦检测到不满足要求就直接抛出 REPLAY(REPLAY继承ERROR) ReplayingDecoder重写了ByteToMessageDecoder的callDecode()方法,捕获Signal并在catch块 中重置ByteBuf的readerIndex。 继续等待数据,直到有了数据后继续读取,这样就可以保证读取到需要读取的数据。

TCP是基于流的,只保证接收到数据包分片顺序,而不保证接收到的数据包每个分片大小。因此在使用 ReplayingDecoder时,即使不存在多线程,同一个线程也可能多次调用decode()方法。在decode中修 改ReplayingDecoder的类变量时必须小心谨慎。

3、连接释放(四次挥手)

主机A不再发送数据,且应用程序释放连接;向主机B发送报文段,包含FIN=1(终止连接),SEQ序号为 x (A之前已经传送的最后一个数据字节序号+1)

主机B收到报文段后,向主机A发送确认ACK,且确认序号为 x+1,且我的报文序号是 y (SEQ=y);同时通知应用程序,主机A的连接释放了,不再向咱们发送数据了。

这时候A不再向B传输数据,但是B还可以向A传输数据。

主机B的应用程序释放连接,不再传输数据,向主机A发送报文段,包含FIN=1(终止连接),SEQ序号为 y (B之前已经传送的最后一个数据字节序号+1)

主机A确认连接释放,向主机B发送确认ACK,且确认需要SEQ= y+1 

断开连接的过程,简单说就是A向B发送消息,我要断开连接,B回复确认;然后B向A发送消息,我要断开连接,A回复确认。发送消息中包含各自的数据字节的序号。

3、HTTP应用

HTTP是在应用层,和TCP不在一个层次上。一个HTTP的请求响应,底层就是TCP建立连接,发送数据,对方数据响应数据,连接关闭的过程。

所以网上说的HTTP长连接,短连接,实际上指的是TCP的连接,

短连接就是每次HTTP请求,都要建立连接,发送数据,接收数据,连接关闭。

长连接就是发送响应数据后,连接不释放,通道维持住,可以复用。(connection:keep-alive)  下次直接发送数据,不再需要建立连接。当然这样也有弊端,多个浏览器或者客户端,如果一直不释放服务器的连接,服务器端连接很快就会耗尽,所以一般长连接会有个时间限制。

 

参考:

  《计算机网络》第四版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值