前言
在做IOT设备的时候经常会用到LWIP开源TCP/IP协议库,特此问题记录以及解决办法
1. LWIP-HTTP无法保持长连接
1.1 问题
在开发http服务器给前端提供数据的时候,网页加载会失败,在http_accepet函数中打桩会看到,浏览器会总是发起请求,造成协议栈溢出。
前端发起一个js请求的时候没有问题,但是发起十几个请求是连续的不同的js请求,每次都是重新连接,而且几乎中间无时间等待,这样会造成http服务器繁忙,资源消耗殆尽然后宕机。
- 解决保持http长连接,http_accept只进一次即可
- 解决浏览器在接到完整的静态页面数据之后再请求下一次
1.2 分析
- 了解http协议以及前端浏览器的工作方式,以下两篇文章记录了服务器端和浏览器端的工作方式,是我想要的。
- 根据1中的说法 ,了解到浏览器是需要知道一次的传输文本是多少,来判断本次的连接是否结束。
- 要想保持长连接,响应头中必须要有connetion:persistant,貌似我的没有
1.3 知识
2. 大量的TIMEWAIT造成资源耗尽
2.1 问题
在使用LWIP开发IOTdev时,我分配了10个PCB,但是因为TIMEWAIT在LWIP中要等待60秒,时间太长了,因为我的设备可能要在16秒内快速使用16个不同PCB块,这样总是造成资源不够,连接不到程序。
2.2 原因
- 发现网页没有建立长连接,因为有RTC每1s轮询每次消耗掉PCB,在TIMEWIAT中等待60s,显然时间太长,资源不够用的。
- TIMEOUT的时间太长了,我觉得在局域网内10s足矣。
2.3 解决方案
- 将TCP_MSL 改成100000UL/10s/
- 增加MEMP_NUM_TCP_PCB 到30个
2.4 知识
2.4.1 TCP/IP详解–TCP连接中TIME_WAIT状态过多
2.4.2 TCP在FIN_WAIT1状态到底能持续多久以及TCP假连接问题
TCP在FIN_WAIT1状态到底能持续多久以及TCP假连接问题
2.4.3 TCP协议RST:RST介绍、什么时候发送RST包
2.4.4 为什么服务器突然回复RST——小心网络中的安全设备
2.4.5 图解网络|收到 RST,就一定会断开 TCP 连接吗?
2.4.6 TCP通信过程中time_wait和close_wait产生过多的原因和解决方法
TCP通信过程中time_wait和close_wait产生过多的原因和解决方法
2.5 网络丢包原因及解决方案
2.5.1. 原因一:物理线路故障
2.5.2. 原因二:设备故障
2.5.3. 原因三:网络拥塞
2.5.3.1 概念:
网络拥塞是一种持续过载的网络状态,此时用户对网络资源(包括链路带宽、存储空间和处理器处理能力等)的需求超过了固有的容量。就Internet的体系结构而言,拥塞的发生是其固有的属性。因为在事先没有任何协商和请求许可机制的资源共享网络中,几个IP分组同时到达路由器,并期望经同一个输出端口转发的可能性是存在的,显然,不是所有分组可以同时接受处理,必须有一个服务顺序,中间节点上的缓存为等候服务的分组提供一定保护。然而,如果此状况具有一定的持续性,当缓存空间被耗尽时,路由器只有丢弃分组,才能保证网络避免出现锁死状况出现。
1. 网络中存在回路导致网速变慢
当网络涉及的节点数不是很多、结构不是很复杂时,这种现象一般很少发生。但在一些比较复杂的网络中,经常有多余的备用线路,如无意间连上时会构成回路。比如网线从网络中心接到计算机一室,再从计算机一室接到计算机二室。同时从网络中心又有一条备用线路直接连到计算机二室,若这几条线同时接通,则构成回路,数据包会不断发送和校验数据,从而影响整体网速。这种情况查找比较困难。为避免这种情况发生,要求我们在铺设网线时一定养成良好的习惯:网线打上明显的标签,有备用线路的地方要做好记载。当怀疑有此类故障发生时,一般采用分区分段逐步排除的方法。
2. 网络设备硬件故障引起的广播风暴而导致网速变慢
作为发现未知设备的主要手段,广播在网络中起着非常重要的作用。然而,随着网络中计算机数量的增多,广播包的数量会急剧增加。当广播包的数量达到30%时,网络的传输效率将会明显下降。当网卡或网络设备损坏后,会不停地发送广播包,从而导致广播风暴,使网络通信陷于瘫痪。
5. 原因四:MTU 配置不当
2.6 TCP协议N问
2.6.1 tcp三次握手过程中丢包该如何处理
2.6.2 tcp四次挥手为什么是四次,为什么不是三次呢?
- 将2次挥手和3次挥手合并成一次挥,不是优化了吗?
因为服务端接到客户端的FIN指令之后,进入到close_wait状态,可能有很多资源没有处理,还有数据要发送,与Last_ack之间甚至相隔3分钟,因为被动断开端需要主动调用close(socket)才能向主动断开端发送FIN报文,将状态迁移到LAST_ACK。
客户端在从established状态迁移到FIN_WAIT_1状态下的时候,一直在等待ack,如果合并了会等带LAST_ACK的FIN_SEQ+ACK,客户端等待30s后超时,会在FIN_WAIT_1的状态下,重发FIN报文,浪费资源。
2.6.3 为什么SYN/FIN 不包含数据却要消耗一个序列号
凡是需要对端确认的,一定消耗TCP报文的序列号。
SYN和FIN需要对端的确认,所以需要消耗一个序列号
2.6.4 什么是半连接队列?什么是SYN Flood 攻击
2.6.5 TCP快速打开(TFO)的原理
TCP快速打开(TCP Fast Open,TFO)
TFO是在原来TCP协议上的扩展协议,他的主要原理就在发送第一个SYN包的时候,就开始传数据了,不过他要求当前客户端之前已经完成【正常】的三次握手。
TCP Fast Open 的优势
一个最显著的优点是可以利用握手去除一个往返 RTT
可以防止SYN-Flood攻击之类的
2.6.6 TCP报文中的时间戳有什么作用
TCP 的时间戳主要解决两大问题:
- 计算往返时延 RTT(Round-Trip Time)
发送一个请求的时候发生了重传,那么这个RTT该怎么计算呢?
RTT = t3-t1 or t3 - t2
在启动 Timestamps选项以后,因为ACK包里包含了TSval 和 Tsecr,这样无论是正常确认包,还是重传确认包,都可以通过这两个值计算出 RTT。
- 防止序列号的回绕问题
假设在发送了6个数据包,而且因为某些原因导致了重传,但是前一个没有丢失,就是在后面的某一时间段,前一个迷途的数据包也收到了,但是这两个数据包的序列号完全一样,有Timestamps 的存在,迷途数据包与其他包可以区分。
2.6.7 TCP的超时重传时间是如何计算的?
TCP具有超时重传机制,即间隔一段时间没有等到数据包的回复时,重传这个数据包。
这个重传间隔也叫做超时重传时间(Retransmission TimeOut,简称RTO)。
如果RTO太小,接收方可能延时一段时间,所以导致不必要的重传。
如果RTO太大,丢包很久RTO才会重传。
2.6.8 TCP的流量控制
2.6.9 如何理解TCP的keep-alive的原理
一个TCP连接上,如果通信双方都不向对方发送数据,那么TCP连接就不会有任何数据交换。
假设应用程序是一个web服务器,客户端发出三次握手以后故障宕机或被踢掉网线,对于web服务器而已,下一个数据包将永远无法到来,但是它一无所知。