小老弟研发之路面筋大汇总——关于计算机网络(一)

  1. 第一次握手:客户端发送位码为syn = 1,随机产生seq number = 1234567的数据包到服务器。(服务端由SYN = 1 知道,客户端要求建立连接)
  2. 第二次握手:服务端收到请求后要确认连接信息,向客户端发送ack number = (客户端的seq number + 1), syn = 1, ack = 1,随机产生seq = 7654321的包。
  3. 第三次握手:客户端收到后,检查ack number是否正确,即第一次发送的seq number + 1 ,以及位码ack是否为1,若正确,主机A再次发送ack number = (服务端的seq + 1),ack = 1。(服务端收到后,确认ack number的值和ack = 1则连接建立成功)
  4. 完成三次握手,客户端与服务器开始传送数据。

大写ACK表示首部中的确认位ACK,小写ack表示确认字段的值


  • TCP 四次挥手原因和过程

为什么要四次挥手:TCP是双向的,所以需要在两个方向分别关闭,每个方向的关闭又需要请求和确认,所以一共4次。

四次挥手过程:

  1. 首先客户端请求关闭客户端到服务端方向的连接,这时客户端就要发送一个FIN = 1,表示要关闭一个方向的连接。
  2. 服务端接收到后是需要确认一下的,所以返回一个ACK = 1
  3. 这时只关闭一个方向,另一个方向也需要关闭,所以服务端也向客户端发一个FIN = 1 
  4. 客户端接收到后发送ACK = 1, 表示接收成功。

 


  • 为什么需要三次握手?

实际上,两次握手就可以建立连接的,为什么还要加第三次确认?

如果发送两次就可以建立连接的话,那么只要客户端发送一个连接请求,服务端接收到并发送了确认,就会建立连接。

但这样就会出现问题,如果一个连接请求在网络中跑得慢,超时了,这时客户端会重新发请求,但是这个跑得慢的请求最后还是跑到了,然后服务端就接收了两个连接请求,然后全部回应就会创建两个连接,浪费资源。

如果加入了第三次客户端确认,客户端在接受到了一个服务端连接确认请求后,后面再接收到的连接确认请求就可以抛弃不管了。


  • TCP流量控制机制

为什么要使用流量控制:一般来说,我们总希望传输数据得更快一些,但假设发送方把数据发送得非常快,而接收方来不及接收,这就可能造成数据的丢失。流量控制就是让发送方的发送速率不要太快,让接收方来得及接收。

流量控制类型:

  1. 滑动窗体机制——针对成块数据流
  2. 捎带ACK和Nagle算法——针对交互数据

滑动窗口机制:

从图中可以看出,B进行了三次流量控制。第一次把窗体降低到rwnd = 300。第二次又减到了rwnd = 100,最后减到rwnd = 0,0即不同意发送方再发送数据了。这样使得发送方暂停发送的状态将持续到主机B又一次发出一个新的窗体值为止。

但是这样可能会导致死锁的局面,为了解决这个问题,TCP为每个连接设有一个持续计时器,仅仅要TCP连接的一方收到对方的零零窗体通知,就启动持续计时器。

糊涂窗体综合征:设想一种情况。TCP接收方的缓存已满。而应用进程一次仅仅从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗体设置为1个字节(但发送的数据报为40字节长)。接收,发送方又发来1个字节的数据(发送方的IP数据报是41字节)。接收方发回确认,仍然将窗体设置为1个字节。这样,网络的效率非常低。要解决问题。可让接收方等待一段时间,或者等到接收方缓存已有一半空暇的空间。仅仅要出现这两种情况之中的一个。接收方就发回确认报文,并向发送方通知当前的窗体大小。 


  • TCP拥塞控制

 

 

 

 

 


  • time_wait?

time_wait状态如何产生:首先主动发起关闭的一方,在发送最后一个ACK之后会进入time_wait的状态,也就是说该发送方会保持2MSL时间之后才会回到最初状态。MSL指的是数据包在网络中的最大生存时间。产生这种结果使得这个TCP连接在2MSL连接等待期间,定义这个四元组(客户端IP地址和端口,服务端IP地址和端口号)不能被使用。

time_wait状态产生的原因:

  1. 为了实现TCP全双工连接的可靠释放。假设发起主动关闭的一方(client)最后发送的ACK在网络中丢失,由于TCP协议的重传机制,执行关闭的一方(server)将会重发FIN,在该FIN到达client前,client必须维护这条连接状态,也就说这条TCP连接所对应的资源(client方的local_ip,local_port)不能被立即释放或重新分配,直到另一方重发FIN到达之后,client重发ACK后,或经过2MSL时间周期没有再收到另一方重发的FIN之后,该TCP连接才能恢复初始的CLOSED状态。如果主动关闭一方不维护这样一个time_wait状态,那么当被动关闭一方重发FIN到达时,主动关闭一方的TCP传输层会用RST包响应对方,这会被对方认为是有错误发生,然而这事实上只是正常的关闭连接过程,并非异常。
  2. 为使旧数据包在网络因过期而消失。为说明这个问题,我们先假设TCP协议中不存在TIME_WAIT状态的限制,再假设当前有一条TCP连接:(local_ip, local_port, remote_ip,remote_port),因某些原因,我们先关闭,接着很快以相同的四元组建立一条新连接。本文前面介绍过,TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分前后两条TCP连接的不同的,在它看来,这根本就是同一条连接,中间先释放再建立的过程对其来说是“感知”不到的。这样就可能发生这样的情况:前一条TCP连接由local peer发送的数据到达remote peer后,会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层(而事实上,在我们假设的场景下,这些旧数据到达remote peer前,旧连接已断开且一条由相同四元组构成的新TCP连接已建立,因此,这些旧数据是不应该被向上传递至应用层的),从而引起数据错乱进而导致各种无法预知的诡异现象。作为一种可靠的传输协议,TCP必须在协议层面考虑并避免这种情况的发生,这正是TIME_WAIT状态存在的第2个原因。
     

time_wait状态如何避免:

首先服务器可以设置SO_REUSEADDR套接字选项来通知内核。

  1. 如果端口忙,但TCP连接位于time_wait状态时可以重用端口。
  2. 另一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一个端口,此时SO_REUSEADDR选项就可以避免time_wait状态。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值