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连接使用同样的端口,可能收到之前连接发出的报文,去掉就会有错乱的问题。通过命令行可以查看:
1 2 3 | # 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。
待续
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单