客户端时不时接收到10054错误

    在一个linux 群里,有人问:select写socket时候 建立链接立马发送数据有时候收不到数据 还提示10054 百分之八十的情况还是能收到的 一般收不到数据的时候 第二次再链接发送数据就能收到 请问是怎么回事呢?

    对于好奇心极强的我,对于这个没遇到的问题,我就百度了10054错误。网上说:

    一般来说是连接被对方重设。一个建立的连接被远程主机强行关闭,若远程主机上的进程异常终止运行(由于内存冲突或硬件故障),或者针对套接字执行了一次强行关闭,便会产生10054错误。针对强行关闭的情况,可用SO_LINGER套接字选项和setsockopt来配置一个套接字。

    而对于 群里描述的那个问题,我回忆了 TCP/IP 协议,我认为会有如下两种情况:

(1)client 在与 server 进行三次握手时,client 调用 connect 函数完成了连接的建立(客户端自以为建立了),而实际server 那边却没有收到最后一次握手 ack 的回复。这时触发了 server 的 syn 触发器,重发 SYN+ACK 包,一般默认是重发 5次,时间分别是 1秒、2秒、4秒、8秒、16秒;而此时client 马上发送数据的话,server 会发 RST 回复给 client, 那么此时 client 就会提示 10054。

(2)而另一种情况就是 server 这边的 accept 队列满了(一般有 syn_recv 队列,accept队列),那么此时 server会直接回复RST(最新的 linux 内核是这么实现的),当然也有可能会拒绝 client的请求,让 client自己自动断开请求。

    群里的一位大神(冒泡)说实现第二种方式,也就是拒绝 client发过来的请求,原因如下:

        第一,服务器已经处理不过来了,再发rst加剧压力
        第二,客户端如果丢包,会等到超时再重试,而收到rst的话有可能立刻重试,服务器压力会更大

你可能感兴趣的:(TCP/IP详解)