网络程序异常退出无core文件产生
这种情况发生在一边连接端已经关闭,但是另外一边还在对连接句柄做send操作,这样做send操作的进程会收到SIGPIPE信号,默认行为是直接退出且不会产生core。为了避免退出,一般在启动的时候加上 signal(SIGPIPE, SIG_IGN) 来忽略这种错误。
发送端send成功,但是接收端却recv失败
send只是表示数据copy到了发送缓冲区,并不代表数据到达了recv,若这时候网络出问题,对面确实收不到数据。
如何让接受方知道发送方每次发送的数据有多长
两种方式
1. 和ip协议类似在每段发送的数据前拼接一个固定长度的包头,包头里存储数据长度类型等信息,接受方那边recv2次,第一次收包头,第二次根据包头里的长度申请空间收数据
2. 和http包头类似,已特殊标记符号为结尾,http是2个\r\n
服务端地址重用问题
服务端重启会被告知端口被占用,这是因为服务端主动调用了close操作。主动断开连接方的端口会在断开以后短时间处于TIME_WAIT状态,这时候端口不能被重用,解决办法是在setsockopt函数里面设置SO_REUSEADDR来保证地址的重用。
为什么会出现TIME_WAIT
四次挥手过程中,主动断开方收到对面的fin包以后要反发一个ack包回复(这是第四次挥手),发完ack以后要等待2个TIME_WAIT(60S)时间才关闭自己,原因是因为ack包会出现丢包的情况,如果出现,对面由于没收到ack可能又会重发fin包,而ack—>fin这一来一回的最长时间正好是2个TIME_WAIT时间,所以主动断开方在等待2个TIME_WAIT时间以后没收到fin就说明ack包已经正常到底对面连接
CLOSE_WAIT状态出现在什么时候
被动关闭方收到对面的fin包以后到发送自己的fin包这段时间网络会处于 CLOSE_WAIT状态,不过这段时间比较短,除非是自己这边网络异常不能关闭连接。
listen的backlog设置
listen里面维护2个队列,一个是已经连接完成的队列,这个长度为backlog,一个是未完成连接的队列,这个长度为backlog/2,accept取的是已完成队列里的句柄,如果accept取的不及时可能导致队列满,这样listen就会拒绝连接