2013-10-09 159 views
0

我是新來的C++。我理解面向對象編程。檢測斷開連接Winsock C++

我跟着一個教程,把這個客戶端/服務器代碼放在一起。我現在想在客戶端斷開連接時向服務器添加消息。

IM使用VS11

服務器:

#include "main.h" 

using namespace std; 

void main () 
{ 
    long answer; 
    WSAData wsaData; 
    WORD DLLVERSION; 
    DLLVERSION = MAKEWORD(2,1); 

    answer = WSAStartup(DLLVERSION, &wsaData); 

    //WINSOCK LOADED 

    SOCKADDR_IN addr; 
    int addrlen = sizeof(addr); 

    SOCKET sListen; 
    SOCKET sConnect; 
    SOCKET* Connections; 
    static int ConCounter = 0; 

    Connections = (SOCKET*)calloc(64, sizeof(SOCKET)); 

    sConnect = socket(AF_INET,SOCK_STREAM,NULL); 

    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    addr.sin_family = AF_INET; 

    addr.sin_port = htons(1234); 


    sListen = socket(AF_INET,SOCK_STREAM,NULL); 

    bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); 

    listen(sListen, SOMAXCONN); 

    for(;;) 
    { 
     cout << "Wating for connection..." <<endl; 

     if(sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen)) 
     { 
      Connections[ConCounter] = sConnect; 

      cout << "Connection found " << ConCounter <<endl; 

      answer = send(Connections[ConCounter], "YourMessage", 12, NULL); 

      ConCounter++; 
     } 
    } 
}  

客戶:

#include "main.h" 

using namespace std; 

void main () 
{ 
    string confirm; 
    char message[200]; 
    string strmessage; 

    long answer; 
    WSAData wsaData; 
    WORD DLLVersion; 
    DLLVersion = MAKEWORD(2,1); 
    answer = WSAStartup(DLLVersion, &wsaData); 

    SOCKADDR_IN addr; 

    int addrlen = sizeof(addr); 

    SOCKET sConnect; 

    sConnect = socket(AF_INET, SOCK_STREAM,NULL); 



    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    addr.sin_family = AF_INET; 


    addr.sin_port = htons(1234); 

    cout << "Do you want to connect to the Server? [Y/N]" <<endl; 
    cin >> confirm; 

    if(confirm == "N") 
    { 
     exit(1); 
    } 
    else 
    { 
     if(confirm == "Y") 
     { 
      connect(sConnect, (SOCKADDR*)&addr, sizeof(addr)); 

      answer = recv(sConnect, message, sizeof(message), NULL); 

      strmessage = message; 
      cout << strmessage <<endl; 

      getchar(); 
     } 
    } 
    getchar(); 
} 

回答

3

你不能用你的本次代碼檢測到它,因爲你所有在場的服務器確實是發送一個消息到一個不太可能失敗的新接受的連接,然後完全忘記了這個連接,包括將它的套接字泄漏到超空間中。您需要爲每個連接啓動一個新線程,該線程將處理該連接上的所有I/O,包括斷開連接(由recv()返回零)或錯誤(由-1表示從send()返回或recv()),或者去異步或多路複用的I/O,這是兩個整體的魚。

+0

所以我需要創建一個函數中的變量定義的套接字? 我知道這聽起來很愚蠢,但是根據我的情況,你現在推薦我學習什麼? 我想用網絡來製作一個C++程序。 我知道Java/PHP/Vb相當不錯,我不知道我在用套接字/線程做什麼。 – contehhh

+0

我不知道你從哪裏得到你的第一句話。它與我所說的任何事情都沒有關係。我建議你閱讀一個基本的網絡程序教程,並確定你的程序實際上是爲了*目前它沒有做任何有用的事情。 – EJP

+0

我以爲你的意思是我需要爲每個線程創建一個套接字。我會定義它在函數中使用一個int在插座名稱的末尾...所以這個名稱將是可變的... – contehhh