2015-07-18 70 views
-1

我正在學習Winsock並試圖創建一些簡單的程序來了解它。我成功地創造出可同時處理多個連接也根據所有教程,它正在它應該怎樣,但管理這些和客戶端服務器:Winsock - 客戶端斷開連接,閉合環路/最大連接數

  • 我試圖使循環,我檢查是否有任何的客戶端有斷開連接,如果有,我想關閉它。

  • 我設法寫的東西,如果插座斷開這將檢查,但不同時連接2個以上的插座

任何人都可以給我答覆如何使工作循環通過每一個客戶檢查如果它已斷開連接並關閉套接字?所有這些都可以讓像max客戶端一樣連接到服務器。提前致謝。

while (true) 
{ 
    ConnectingSocket = accept (ListeningSocket, (SOCKADDR*)&addr, &addrlen); 
    if (ConnectingSocket!=INVALID_SOCKET) 
    { 
     Connections[ConnectionsCounter] = ConnectingSocket; 
     char *Name = new char[64]; 
     ZeroMemory (Name,64); 
     sprintf (Name, "%i",ConnectionsCounter); 
     send (Connections[ConnectionsCounter],Name,64,0); 
     cout<<"New connection !\n"; 
     ConnectionsCounter++; 
     char data; 
     if (ConnectionsCounter>0) 
     { 
      for (int i=0;i<ConnectionsCounter;i++) 
      { 
       if (recv(Connections[i],&data,1, MSG_PEEK)) 
       { 
        closesocket(Connections[i]); 
        cout<<"Connection closed.\n"; 
        ConnectionsCounter=ConnectionsCounter-1; 
       } 
      } 
     } 
    } 
    Sleep(50); 
} 
+1

的可能重複[我如何檢查是一個套接字仍然是開放的?](http://stackoverflow.com/questions/851654/how-can-i-check-is- a-socket-is-still-open) – Jorj

+0

您提供的示例代碼未提供足夠的詳細信息以提供幫助。提供的代碼是循環中調用的函數的一部分嗎?你在調試器中看到了什麼? – Coder

+1

@advent爲什麼拒絕編輯您的示例代碼?它的格式是不可讀的。 – Coder

回答

-2

看來你想用單個線程管理多個連接。對? 簡單的socket通信有兩種模式,分塊和非分塊。默認的是塊模式。讓我們專注您的代碼:

for (int i=0;i<ConnectionsCounter;i++) 
{ 
    if (recv(Connections[i],&data,1, MSG_PEEK)) 
    { 
     closesocket(Connections[i]); 
     cout<<"Connection closed.\n"; 
     ConnectionsCounter=ConnectionsCounter-1; 
    } 
} 

在上面的代碼中,您調用了recv函數。並且它會阻止,直到對方發送了消息給你,或者對方關閉鏈接。所以,如果你現在有兩個連接,即連接[0]和連接[1]。如果您是recv Connections [0],同時連接[1]已斷開,您不知道它。因爲你在recv處阻塞(Connections [0])。當Connections [0]發送msg給你,或者它關閉套接字,然後循環繼續,最後你檢查它斷開連接,即使它在10分鐘前斷開連接。

爲了解決這個問題,我認爲你需要一本書微軟Windows網絡編程。有一些方法,例如一個線程一個套接字模式,異步通信模式,非阻塞模式等等。


忘記指出的錯誤,在這裏要注意:

closesocket(Connectons[i]); 
cout<<"Connection closed.\n"; 
ConnectionsCounter=ConnectionsCounter-1; 

我舉一個例子來說明它。現在我們有兩個連接索引0和1,然後ConnectionsCount應該是2,對吧?當Connections [0]斷開連接時,ConnectionsCounter從2更改爲1.並退出循環,一個連接的新客戶端將新客戶端套接字保存爲Connections [ConnectionsCounter(= 1)] = ConnectingSocket;哎呀,有一個錯誤。因爲斷開連接的套接字的索引是0,並且索引1被另一個鏈接使用。您正在重新使用索引1.

爲什麼不嘗試使用向量來保存套接字。

希望它幫助〜

+0

是的,我正在使用單線程。我已經解決了這個問題,但是我在這個多連接檢查中丟失了一些東西。使用recv使我的服務器能夠只關注單個客戶端,其他客戶端必須等到另一個客戶端關閉。 – Advent

+0

這就是我想到的,我看到類Socket有一個叫做isDisconnected的方法,或者類似的東西,所以也許使用這將是一個好主意。我還有很多東西需要學習,我對如何嘗試實現這些和其他東西有很多想法,但是我需要一些時間才能理解它的工作原理並能夠流利地進行工作。感謝您的關注和好的建議,這真的很有幫助。 – Advent

+0

從頭到尾完全不正確。如果在您檢查本節點時另一個節點斷開連接,您將在稍後檢查時發現它。斷開連接事件不會被丟棄。檢測對等連接斷開的唯一方法是嘗試從套接字讀取。沒有其他套接字方法可能會告訴你。不要在這裏發佈錯誤信息。 – EJP