2011-04-03 54 views
0

我正在編寫,運行,調試客戶端連接到的FreeBSD上的TCP服務器。當服務器崩潰或有些不正常時,我經常遇到問題,因爲我的bind()調用失敗,導致服務器無法備份。當發生這種情況,當然我能找到的netstat -n如下:我的TCP代碼中的FIN_WAIT_2阻止打開套接字

Active Internet connections 
Proto Recv-Q Send-Q Local Address   Foreign Address  (state) 
tcp4  0  0 192.168.2.xxx.12345 xx.yy.zz.ww.54201  FIN_WAIT_2 

這是相當刺激性的,因爲我在這裏坐一分鐘或2或3,直到它清除出去。我已經盡了最大努力避免這種情況:

if((socketId = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) ... 

// Set socket to nonblocking. If this is < 0 there was a failure 
if(fcntl(socketId, F_SETFL, O_NONBLOCK) < 0) ... 


// Linger settings 
struct linger so_linger; 
so_linger.l_onoff = 1; // Turn linger option TRUE! 
so_linger.l_linger = 0; // And inform to DO NOT LINGER 


if(setsockopt(socketId, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) ... 

那麼,爲什麼我收到了揮之不去的行爲?這是在FreeBSD上,但在我移植我的代碼之前,我在Linux上遇到了同樣的問題。我試圖將代碼放在代碼中,以便在「control-c」殺死我的服務器時,它應該在所有這些套接字上運行並立即退出。這似乎沒有幫助

+1

嘗試設置SO_REUSEADDR和SO_REUSEPORT - 如果其中任何一個可用於fbsd。 – Erik 2011-04-03 19:12:46

回答

2

嘗試設置套接字選項SO_REUSEADDR

SO_REUSEADDR表示在驗證bind(2)調用中提供的地址時使用的規則應允許重用本地地址。

AIUI中,O/S通常不會讓你bind如果有一個插座留在該端口上游逛,而這個電話應該告訴O/S允許它。

+0

工程就像一個魅力。謝謝 – Nektarios 2011-04-03 19:24:30

0

你也可以看看相關的sysctl:

  • net.inet.tcp.fast_finwait2_recycle
  • net.inet.tcp.finwait2_timeout

設置循環= 1和超時下來到一個理智的東西(5k毫秒,你的里程可能會有所不同)對我的一個盒子有很大的幫助..

HTH :)

-jamie

相關問題