2013-02-21 106 views
-5

我正在嘗試爲客戶端/服務器聊天程序編寫服務器。 唯一的問題是,如果一旦客戶端斷開連接,服務器就會開始向服務器發送垃圾郵件。即使他們重新連接,它也會持續發送垃圾郵件。我嘗試了Google搜索,但找不到任何內容。 這裏的服務器代碼:(WinSocket)垃圾郵件斷開

#include "MasterServer.h" 
using namespace std; 
SOCKADDR_IN Server; 
int addrlen = sizeof(Server); 
SOCKET sListen; 
SOCKET Connect; 
SOCKET* Connections; 
int port = 444; 
int ConCounter = 0; 
char* Recv = new char[256]; 
int ServerThread(int ID) 
{ 

ZeroMemory(Recv, sizeof(Recv)); 
for(;;) 
{ 
    if(recv(Connections[ID],Recv ,256 ,NULL)) 
    { 
     cout << Recv << endl; 
    } 
} 
} 

int InitWinSock() 
{ 
int RetVal = 0; 
     WSAData wsa; 
     WORD Version = MAKEWORD(2,1); 
     RetVal = WSAStartup(Version, &wsa); 

     return RetVal; 
} 


int main() 
{ 
    int RetVal = 0; 
    RetVal = InitWinSock(); 
    if(RetVal != 0) 
    { 
     cout << "WinSock Start Up Failure"; 
    } 
     Connections = (SOCKET*)calloc(64, sizeof(SOCKET)); 

     sListen = socket(AF_INET, SOCK_STREAM, NULL); 
     Connect = socket(AF_INET, SOCK_STREAM, NULL); 
     cout << "\t\t----====ModernBacon Server====----"<< endl; 

     cout << "What Port Would You Like To Run On [Default 444]: "; 
     cin >> port; 

     system("cls"); 
     Server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
     Server.sin_family = AF_INET; 
     Server.sin_port = htons(port); 

     bind(sListen, (SOCKADDR*)&Server, sizeof(Server)); 
     //Listening 
     listen(sListen, 64); 
cout << "Listening For Connections IP:"<<inet_ntoa(Server.sin_addr);"Port:"<<port<< 
endl; 


     for(;;) 
      { 
      if(Connect = accept(sListen, (SOCKADDR*)&Server, &addrlen)) 
      { 
       Connections[ConCounter] = Connect; 
       char* ID = new char[64]; 
       ZeroMemory(ID, sizeof(ID)); 
       itoa(ConCounter, ID, 10); 
       send(Connections[ConCounter], ID, sizeof(ID),NULL); 

       ConCounter = ConCounter + 1; 
       CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE) 
ServerThread, (LPVOID)(ConCounter -1), NULL, NULL); 

       cout << "\t\tClient Connected!\tID: " << 
ConCounter << endl; 



      } 

     } 
     return(0); 
} 

我不知道怎麼回事......

+2

你知道什麼'recv'返回錯誤? – 2013-02-21 19:35:19

+0

當客戶端斷開分配給它們的線程時,永遠不會消失。當一個新的客戶端被分配到該連接ID時,會發生什麼?而且,你的所有線程都共享*相同的緩衝區以便從套接字讀取。那是另一場災難。 – 2013-02-21 19:35:21

+0

Joachim,不,我不知道。 – 2013-02-21 19:48:26

回答

0

有相當與您的代碼的幾個問題。嘗試更像這樣的代替:

#include "MasterServer.h" 
#include <string> 

using namespace std; 

static const int MAX_CLIENTS = 64; 
static const int MAX_RECV = 256; 

struct ClientInfo 
{ 
    int ID; 
    SOCKET Connection; 
    char Recv[MAX_RECV]; 
}; 

ClientInfo Clients[MAX_CLIENTS]; 

DWORD WINAPI ServerThread(LPVOID lpParam) 
{ 
    ClientInfo *Client = (ClientInfo*) lpParam; 
    char szID[64] = {0}; 

    itoa(Client->ID, szID, 10); 

    int RetVal = send(Client->Connection, szID, sizeof(szID), NULL); 
    if (RetVal != sizeof(szID)) 
    { 
     cout << "Client " << Client->ID << " Send Failure. Error " << WSAGetLastError() << endl; 
    } 
    else 
    { 
     do 
     { 
      RetVal = recv(Client->Connection, Client->Recv, MAX_RECV, NULL); 
      if (RetVal == SOCKET_ERROR) 
      { 
       cout << "Client " << Client->ID << " Recv Failure. Error " << WSAGetLastError() << endl; 
       break; 
      } 

      if (RetVal == 0) 
      { 
       cout << "Client " << Client->ID << " disconnected" << endl; 
       break; 
      } 

      cout << "Client " << Client->ID << ": " << string(Client->Recv, RetVal) << endl; 
     } 
     while (true); 
    } 

    closesocket(Client->Connection); 
    Client->Connection = INVALID_SOCKET; 

    return 0; 
} 

int InitWinSock() 
{ 
    WSAData wsa; 
    return WSAStartup(MAKEWORD(2,1), &wsa); 
} 

int main() 
{ 
    SOCKADDR_IN addr; 
    int addrlen; 
    SOCKET sListen; 
    SOCKET sClient; 
    int port = 444; 
    int index; 

    cout << "\t\t----====ModernBacon Server====----"<< endl; 

    for (int i = 0; i < MAX_CLIENTS; ++i) 
     Connections[i] = INVALID_SOCKET; 

    int RetVal = InitWinSock(); 
    if (RetVal != 0) 
    { 
     cout << "WinSock Start Up Failure. Error " << RetVal << endl; 
     return 0; 
    } 

    sListen = socket(AF_INET, SOCK_STREAM, NULL); 
    if (sListen == INVALID_SOCKET) 
    { 
     cout << "WinSock Socket Failure. Error " << WSAGetLastError() << endl; 
     return 0; 
    } 

    cout << "What Port Would You Like To Run On [Default 444]: "; 
    cin >> port; 
    system("cls"); 

    ZeroMemory(&addr, sizeof(addr)); 
    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 

    RetVal = bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); 
    if (RetVal != 0) 
    { 
     cout << "WinSock Bind Failure. Error " << WSAGetLastError() << endl; 
     return 0; 
    } 

    //Listening 
    RetVal = listen(sListen, MAX_CLIENTS); 
    if (RetVal != 0) 
    { 
     cout << "WinSock Listen Failure. Error " << WSAGetLastError() << endl; 
     return 0; 
    } 

    cout << "Listening For Connections. IP: " << inet_ntoa(addr.sin_addr) << ", Port: " << port << endl; 

    do 
    { 
     addrlen = sizeof(addr); 
     sClient = accept(sListen, (SOCKADDR*)&addr, &addrlen); 
     if (sClient == INVALID_SOCKET) 
     { 
      cout << "WinSock Accept Failure. Error " << WSAGetLastError() << endl; 
      return 0; 
     } 

     index = -1; 
     for (int i = 0; i < MAX_CLIENTS; ++i) 
     { 
      if (Clients[i].Connection == INVALID_SOCKET) 
      { 
       index = i; 
       break; 
      } 
     } 

     if (index == -1) 
     { 
      closesocket(sClient); 
      cout << "\t\tClient Connected. Max Clients Exceeded!" << endl; 
      continue; 
     } 

     Clients[index].ID = index + 1; 
     Clients[index].Connection = sClient; 

     CreateThread(NULL, NULL, &ServerThread, &Clients[index], NULL, NULL); 

     cout << "\t\tClient Connected!\tID: " << Clients[index].ID << endl; 
    } 
    while (true); 

    return 0; 
}