linux sock 乙個奇怪問題

2021-07-26 07:14:51 字數 1745 閱讀 7093

今天查乙個問題,反饋的日誌中,看到服務端乙個網路套接字sock 被設定成o_nonblock了,但是在read的時候,報錯了。

用strerror(errno),列印錯誤資訊,看到是connection timed out 。

這就詭異了,按理說,設定成o_nonblock了,就不會有time out的,加日誌除錯的

struct timeval ti;

ti.tv_sec=0;

ti.tv_usec=0;

socklen_t len=sizeof(ti);

getsockopt(rcc->stream->socket,sol_socket,so_rcvtimeo,&ti,&len);

將這裡的timeout超時時間也列印出來,看看是不是真有time out大於0那麼邪門。除錯時發現,這裡ti.tv_sec 和 ti.tv_usec都是0。

那這個connect time out是什麼意思?**報的錯誤?

從看到tcp是面向連線的,當tcp檢測到對端socket不再可用時(不能發出探測包,或探測包沒有收到ack的響應包),

select會返回socket可讀,並且在recv時返回-1,同時置上errno為etimedout。

這個解釋剛好和我們服務端的**可以對得上。

原來在客戶的應用場景,網路延時是比較大的(20ms左右),偶爾還有網路抖動。而且這個tcp連線還沒有自己的心跳包,用的是tcp協議預設的心跳。

這個心跳值可以在**設定,也可以在/etc/sysctl.conf 設定

net.ipv4.tcp_keepalive_intvl = 30 這樣就可以將該系統上執行的程序,tcp通訊的描述為設定預設心跳為30秒。

因為我們的伺服器沒有配置這個項,所以就用了linux核心的預設值,linux 2.6.24

#ifndef hz

#define hz 100

#endif

#define tcp_keepalive_intvl(75*hz)

所以是 7500秒,2個多小時才發出的乙個心跳。在這種網路延時下,經過那麼久才檢查,tcp檢測到對端socket 時,客戶端的變成不再可用是很正常不過了。

怎麼解決?

在客戶端對sock套接字,加入心跳包,頻繁一點檢查,檢查到斷開了,就進行重新連線。

int keepalive=1;//開啟keepalive屬性

int keepidle=30;//如該連線在30秒內沒有任何資料往來,則進行探測

int keepinterval=2;//探測時發包的時間間隔為2秒

int keepcount=3;//探測嘗試的次數。如果第1次探測包就收到響應了,則後2次的不再傳送

if(setsockopt(_peer,sol_socket,so_keepalive,(void *)&keepalive,sizeof(keepalive))!=0)//若無錯誤發生,setsockopt()返回值為0

if(setsockopt(_peer,sol_tcp,tcp_keepidle,(void *)&keepidle,sizeof(keepidle))!=0)

if(setsockopt(_peer,sol_tcp,tcp_keepintvl,(void *)&keepinterval,sizeof(keepinterval))!=0)

if(setsockopt(_peer,sol_tcp,tcp_keepcnt,(void *)&keepcount,sizeof(keepcount))!=0)

乙個很奇怪的問題

if equipmentlist.size 0 string equipidarray new string 3 for int i 0 i equipmentlist.size i element equipment element equipmentlist.get i string equip...

innerHTML的乙個奇怪問題

背景 使用ajax翻頁 起初 是這樣的 頁面 include cn videoplay comment listcomment.ftl ajax comment innerhtml originalrequest.responsetext 在firefox下是好的,在ie下頁面會掛在那不動,經檢測a...

innerHTML的乙個奇怪問題

背景 使用ajax翻頁 起初 是這樣的 頁面 include cn videoplay comment listcomment.ftl ajax comment innerhtml originalrequest.responsetext 在firefox下是好的,在ie下頁面會掛在那不動,經檢測a...