首页 > 技术文章 > 网络编程基础

ralgo 2020-12-13 15:08 原文

TIME_WAIT

1、主动关闭socket方会进入TIME_WAIT状态
2、客户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释),进入CLOSED状态。
3、MSL一般Linux中一个MSL是30秒,是不可配置的。
4、存在的意义:像一堵墙一样为对应端口挡住上次连接姗姗来迟的数据报文,如果马上进入CLOSED状态并被再次使用,新的连接可能会因为旧连接的数据报文发生异常。

FIN_WAIT_2


主动关闭方接收了对方的ACK后便会从FIN_WAIT_1转变成FIN_WAIT_2,那么什么情况下对方迟迟不发出FIN包,导致这条连接一直处于FIN_WAIT_2状态呢?一个常见的例子就是连接池,tomcat默认情况下只允许空闲连接和自己保持60秒的连接时间,超过这个时间,tomcat会主动关闭该空闲连接,然后就进入FIN_WAIT_1状态。客户端由于使用的是连接池,它并不会实时地监控连接的状态(比如用epoll监控),所以在操作系统层面发送了ACK后,客户端不会知道这条连接是已经关闭的然后一直保持这种半开状态,直到下次使用这条连接时它才会从IO操作中获知此连接已经关闭并主动关闭掉连接。

SIGPIPE

当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
又或者当一个进程向某个已经收到RST的socket执行写操作是,内核向该进程发送一个SIGPIPE信号。该信号的缺省学位是终止进程,因此进程必须捕获它以免不情愿的被终止。
根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。若不想客户端退出可以把 SIGPIPE设为SIG_IGN

EINTR

如果进程在一个慢系统调用(slow system call)中阻塞时,当捕获到某个信号且相应信号处理函数返回时,这个系统调用不再阻塞而是被中断,就会调用返回错误(一般为-1)&&设置errno为EINTR(相应的错误描述为“Interrupted system call”)。
遇到这个错误一般都需要重试。

不要在linux的select中设置入大于或等于1024的文件描述符

因为linux平台下的FD_SET用的是位图来保存文件描述的设置情况,关键点就是这个位图只有1024个位,一旦FD_SET用大于或等于1024的文件描述符,就会发生位溢出,程序随时都有可能崩溃。

推荐阅读