(tcp protocol) 网络异常

socket需要由物理链路来传输,而这会导致很多的异常情况,下面对几种异常情况做下笔记。

建立连接,三次握手

建立连接会有3个包,分别为syn, syn ack, ack,当中某个包丢失都会导致建立连接失败。

下面列一下正常状态迁移:

c端首先发送syn

c None->SYN_SEND (send syn)

s端收到了syn包后,转为SYN_RECV,同时发送syn ack。在这儿,s端会把该连接放入backlog。backlog主要是防止大量建立半连接导致服务端无法服务正常连接的攻击的。

s None->SYN_RECV (recv syn, send syn ack)

c端收到了syn ack后,会转为established状态,该半连接已经建立,同时发送ack回s端。

c SYN_SEND->ESTABLISHED (recv syn ack, send ack)

s端收到了ack后,该连接已建立,转为established状态,同时放入accept-queue处理。当accept-queue满了后,会拒绝连接。

s SYN_RECV->ESTABLISHED (recv ack)

  1. c端连接了s端一个未监听的端口

在这种情况下,s端会返回一个rst (Connection refused)

  1. c端与s端的网络不通

可能会返回网络不可达,也可能会超时。在超时前由于syc发出而没有回应,会不断的重发,直到到达某个尝试次数,然后返回超时。

  1. 有包丢失

1) syn丢失。在这个情况下,底层协议会不断的重发syn,直到返回超时或者不可达。

2) syn ack丢失。在这个情况下,主动连接一方由于没有收到syn ack,会不断的重发syn包,这个和1)相似。对于s端,由于已经收到了syn包,所以处于syn_recv状态,不断的回syn ack,会导致资源消耗。

3) ack丢失。在这个情况下,由于c端已经处于了established状态,所以理论上已经可以使用send来发包了。然而s端还处于syn_recv状态,在这段时间内,s端会不断的重发syn ack。c端发包后,由于s端不处于established状态,所以该包是发不到s端的,于是在底层协议的实现里,c端的发包会不断的重试,

共 0 条回复
暂时没有人回复哦,赶紧抢沙发
发表新回复

作者

sryan
today is a good day