客戶端怎麼判斷Socket連線已與伺服器斷開
First of all , Server's socekt is not close.
if u had closed client's socekt , u should creat it again when u want to connect server's.
socket即使close了,也還是會存在的,除非設定socket的option,設定為立即close
看一下setsockopt()這個函式吧
附一朋友的問題:
伺服器程式為Socket Sever,繫結12005埠,啟動就Listen,然後客戶端不停的連線、斷開,在每天4點伺服器程式自動關閉後,又由另外一個守候程式開啟。伺服器執行8-9天后,客戶端不能連線了,連線的客戶端也請求不了資料,就是說伺服器程式不接受SOCKET連線了,傳送的資料在OnReceive()不能接受了,在這個時間用遠端登入可以登入到伺服器,CPU也是4%左右,自己的伺服器程式用記憶體也是不到10M(曾經到過70M也沒問題),資料的一條線城也沒有堵塞(當時自己開啟SQL2000企業管理器檢視到的),關閉自己伺服器程式,客戶端又可以連線上來,但是過了2個小時又是上面的情況,這次關閉自己伺服器程式也不能連線了,只好將作業系統關閉,重新啟動伺服器機器,重起後可以了。
又要執行到8-9天后才發生重複的事情、、、,好奇怪呀,已經連續發生4次了,找不到原因,
自己認為
1、是不是作業系統的埠8-9天后用完了?如果是
2、記憶體用完了?(1G系統記憶體,在資源管理器看到是一直穩定到830M左右)
---------------------------------------------------------------------------------------------------
TCP連線如果不收發資料,大約幾十秒之後就會超時,超時之後伺服器端不會收到OnClose()
這樣一來,就會有許多死連線,伺服器端無法清除。
b/S之間沒有資料傳送的時候要傳送一些線上包,比如說,沒有資料傳輸時每20秒傳送一個空格
Server端對每個連線定時檢測,大概象下面這樣:
OnRecv()
{
last_recv_time = GetTickCount();
//do recv() here
}
OnTimer()
{
if(GetTickCount()-last_recv_time>35000)//close connection any way after 35 seconds' idle
{
closesocket(s)
}
}
客戶端要有重連機制
C#中判斷socket是否已斷開的方法
在C#中,Socket類的Connected屬性只表示最後一次I/O操作的狀態,如果這之後[連線的另一方]斷開了,它還一直返回true, 除非你再通過socket來發送資料。所以通過這個屬性來判斷是行不通的!
有人說可以用Socket.Available屬性來判斷,msdn中說:如果[連線的另一方]斷開了,它就會丟擲異常。然而,這個BUG報告(http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/)卻指出:msdn的說法並不完全正確,這個屬性只有在少數情況下才丟擲異常。所以,這一招還是行不通!
事實上,Socket.Receive()方法在[連線的另一方]斷開時,它返回結果告知只讀了0個位元組,我們可以籍由這一點來找出答案。這個問答(
Socket s = new Socket(..);
if (s.Poll(-1, SelectMode.SelectRead))
{
int nRead = s.Receive();
if (nRead == 0)
{
//socket連線已斷開
}
}
如果您還有更好的方法,也請告訴我, :).