网络常见问题背后的原因

1. 为啥程序启动的时候,总是有"bind address" 错误,通常通过设置socket REUSEADDR,就可以解决这个问题。但是这个问题的背后是什么原理?
     一般是计算机程序,都是通过socket建立了基于tcp连接的网络应用,常见的就是实现http请求的应用,绑定了host主机的端口,
    因为计算机端口占用后,需要等待一段时间后才能使用,如果使用netstat 命令查看,可以看到该端口在FIN_WAIT2中,如下面的例子:
 jet@ubuntu-server:~$ sudo netstat -pt

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    

tcp        0      0 localhost:8787          localhost:39770         FIN_WAIT2   -    

 

那么FIN_WAIT2 的状态是说明服务正在等待对端发FIN,ACK进行四次挥手的确认,但是由于服务端已经被停止了,所以这个流程被打断了,导致这个状态一直停留在这个状态。但是过一阵子,又tcp连接消失了,又可以bind绑定了。那是连接被内核接管,(类似孤儿进程)的孤儿连接。Linux为了防止孤儿连接长时间存留在内核中,定义了两个内核变量:

/proc/sys/net/ipv4/tcp_max_orphans,  内核能够接管的孤儿连接数目

/proc/sys/net/ipv4/tpc_fin_timeout   孤儿连接在内核中生存的时间。

如果是按照正常的流程走,FIN_WAIT2会接受到对端的FIN报文,而进入TIME_WAIT
2. 有几种wait ?
   有好几种wait,关键角色主要看哪一端为主动发起关闭方。
 close_wait, fin_wait1, fin_wait2, time_wait
   time_wait 一般是 2MSL (MSL max sgement lifetime), MSL是指 IP 报文段在网络存活的最大时间,两倍的意思是一来一回,实际中一般是30秒,1分钟或者是2分钟。通过命令行可以查看:
   cat /proc/sys/net/ipv4/tcp_fin_timeout 60
   之所以time_wait 需要等待2MSL,是因为根据tcp状态转移图,被动关闭方等待time_wait2 发过来的ack报文过程中,没有收到ack,并不能关闭连接,被动关闭方会重发FIN报文。由于主动方还处于time_wai期间,接受到FIN报文,可以重新发送ack报文给被动方。如果耗尽了2MSL(发送耗时1MSL,接受应答耗时MSL)都没有收到重发的报文,那么主动方直接关闭连接。
   MSL 并不是TTL(time to live),这个是指一个IP数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。
 
3. time_wait 为啥存在,能否它直接干掉不好嘛?
    time_wait过多,导致端口占用过多,而端口是有限的,这对于主机是一大危害。通过设置linux主机的参数,可以减少time_wait 。但是这些是治标不治本。要解决问题的本质,为什么导致time_wait太多。
     首先,在linux 主机出现time_wait,不合理,从tcp状态转移图可以看出,是主动调用方关闭tcp连接才会发生time_wait. 证明有过频繁的对外tcp请求建立与断开。考虑使用长连接,keep alive,避免频繁不停创建关闭过多的tcp连接
     其次,time_wait 在网络中存在本身就为了防止错乱报文的作用,避免由于新的tcp连接使用同样的端口,可能收到之前连接发出的报文,去掉就会有错乱的问题。通过命令行可以查看:
# netstat -s |grep reject
    2181 passive connections rejected because of time stamp
    34 packets rejects in established connections because of timestamp
     比如通过开启tcp_timestamp和tcp_tw_recycle这个两个选项来减少time_wait,容易导致NAT情况下,误认为多个客户端为同一个源头发出的报文,根据tcp 的时间戳先后,把一些实质上是不同应用发出的报文过滤掉。这个是由于Per-host PAWS机制导致的。
 
4. NAT 啥意思?
    Native Address Translation。 其中有一个 NAPT,Native Address Port Translation,例子就是家里被分配一个IP,为啥连接路由器的设备各自有自己的IP,而且还能正常访问外部网络。那是路由器通过IP加端口建立一种映射关系,建立了外部网络与内部设备的连接关系。
 
5. Per-host PAWS机制?
     PAWS(Protect Against Wrapped Sequence numbers,是一个简单的防止重复报文的机制)中,来丢弃当前连

接中可能的旧的重复报文。而Linux实现这个机制的方法就是同时启用net.ipv4.tcp_timestamps和net.ipv4.tcp_tw_recycle
这两个选项。

  在高带宽下,TCP序列号可能在较短的时间内就被重复使用(recycle/wrapped),就可能导致同一条TCP流在短时间内出现序号一样的两个合法的数据包及其确认包!

  AWS机制就是为了应对这一现象设计的,这种机制要求所有来个同一个host IP的TCP数据包的timestamp值是递增的。当收到一个timestamp值,小于服务端记录的对应值后,则会认为这是一个过期的数据包,然后会将其丢弃

 
5. 城中村上网为啥有各种的广告嵌套? 从城中村说起 https http, http 1.0 1.1 2.0 协议。
    那是无良的ISP运营商,在你请求网页的时候,加入了自己的广告。这也是当初苹果当初为啥要强行推行使用https的一原因,因为我们请求的数据,在传输过程中,不但被人获取,而且还可以被人任意修改。所以我们要使用https。
    待续
 
 
原文地址:https://www.cnblogs.com/studyNT/p/13658811.html