2014-09-18 143 views
-1

我想讓我的服務器分配客戶端ID,但是每當我將客戶端連接到服務器時,服務器崩潰。Winsock2錯誤:連接到客戶端時服務器崩潰

服務器:

#include <iostream> 
#include <winsock2.h> 
#include <string> 

#define PORT 25444 
#define MAX_CLIENTS 2 
#define BUFLEN 512 

int main() 
{ 

    SOCKET s; 

    unsigned int Max = MAX_CLIENTS - 1; 
    unsigned int ID[ Max ]; 

    std::string Address[ Max ]; 

    struct sockaddr_in server, si_other; 

    int slen, recv_len; 

    char buf[ BUFLEN ]; 

    WSADATA wsa; 

    slen = sizeof(si_other); 

    if (WSAStartup(MAKEWORD(2, 2), & wsa) != 0) 
    { 

     std::cout << "NETWORK ERROR: Failed to initialise. Error code: " << WSAGetLastError() << "\n"; 

    } 

    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) 
    { 

     std::cout << "NETWORK ERROR: Failed to create socket. Error code: " << WSAGetLastError() << "\n"; 

    } 

    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(PORT); 

    if (bind(s, (struct sockaddr *) & server, sizeof(server)) == SOCKET_ERROR) 
    { 

     std::cout << "NETWORK ERROR: Failed to bind to port. Error Code: " << WSAGetLastError() << "\n"; 

    } 

    while(1) 
    { 

     bool AddClient; 
     unsigned int TimesLooped; 

     memset(buf, '\0', BUFLEN); 

     if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) & si_other, & slen)) == SOCKET_ERROR) 
     { 

      std::cout << "NETWORK ERROR: Failed to read from the port. Error code: " << WSAGetLastError() << "\n"; 

     } 
     else 
     { 

      TimesLooped = 0; 

      for (int i = 0; i <= Max; i++) 
      { 

       if (inet_ntoa(si_other.sin_addr) != Address[ i ]) 
       { 

        AddClient = true; 

       } 
       else 
       { 

        AddClient = false; 

        i = Max; 

       } 

       TimesLooped++; 

      } 

      if (AddClient) 
      { 

       Address[ TimesLooped ] = inet_ntoa(si_other.sin_addr); 
       ID[ TimesLooped ] = TimesLooped; 

      } 

     } 

     std::cout << "NETWORK: Received packet from " << inet_ntoa(si_other.sin_addr) << ":" << ntohs(si_other.sin_port) << "(Client ID: " << ID[ TimesLooped ] << ")" << "\n"; 
     std::cout << "NETWORK: Data: " << buf << "\n"; 

     if (sendto(s, buf, recv_len, 0, (struct sockaddr *) & si_other, slen) == SOCKET_ERROR) 
     { 

      std::cout << "NETWORK ERROR: Failed to send data through the port. Error code: " << WSAGetLastError() << "\n"; 

     } 

    } 

    closesocket(s); 

    WSACleanup(); 

    return 0; 

} 

客戶:

#include <string> 
#include <iostream> 
#include <winsock2.h> 

#define IP "127.0.0.1" 
#define PORT 25444 
#define BUFLEN 512 

using namespace std; 

void SendPacket(string message) 
{ 

    struct sockaddr_in si_other; 

    int s, slen = sizeof(si_other); 

    char buf[ BUFLEN ]; 

    char msg[ BUFLEN ]; 

    strcpy(msg, message.c_str()); 

    WSADATA wsa; 

    if (WSAStartup(MAKEWORD(2, 2), & wsa) != 0) 
    { 

     cout << "ERROR: Network failed to initialise. Error code: " << WSAGetLastError() << "\n"; 

    } 

    if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) 
    { 

     cout << "ERROR: Network failed to create socket. Error code: " << WSAGetLastError() << "\n"; 

    } 

    memset((char *) & si_other, 0, sizeof(si_other)); 
    si_other.sin_family = AF_INET; 
    si_other.sin_port = htons(PORT); 
    si_other.sin_addr.S_un.S_addr = inet_addr(IP); 

    if (sendto(s, msg, strlen(msg), 0, (struct sockaddr *) & si_other, slen) == SOCKET_ERROR) 
    { 

     cout << "ERROR: Network failed to send data through the port. Error code: " << WSAGetLastError() << "\n"; 

    } 

    memset(buf, '\0', BUFLEN); 

    if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) & si_other, & slen) == SOCKET_ERROR) 
    { 

     cout << "ERROR: Network failed to read from the port. Error code: " << WSAGetLastError() << "\n"; 

    } 

    closesocket(s); 

    WSACleanup(); 

} 

int main() 
{ 

    SendPacket("Test"); 

    return 0; 

} 

我希望能有客戶端的ID,這樣我可以跟蹤哪些IP是哪個,然後當我需要發送的數據包對於客戶,我可以通過Address[ ID ];參考客戶ID來完成。服務器和客戶端運行正常,沒有客戶端ID的代碼。請幫忙。任何關於如何改進代碼或其他方式來做到這一點的建議都沒有問題。

回答

0

在你的代碼中,你的Address數組只有一個元素。 MAX_CLIENTS是2.最大值是2 - 1或1,所以只有地址[0]有效。你從0循環到1,所以每次你引用索引1時,我都不會驚訝於看到崩潰。

看看std :: map,例如here.一本字典會處理你的搜索。我會使用std :: map處理客戶端ID表。

此外,您的客戶端密鑰僅使用IP地址,而不是客戶端的端口。如果兩個客戶端使用相同的IP地址連接,他們將共享您的客戶端ID。您可能希望將端口號包含在ID字符串中。

+0

我認爲數組從0開始不是一個,所以當我定義MAX_CLIENTS爲2時,我在Max中遞減它,以便唯一可用的將是0和1.我將查看std :: map並改進代碼,而且我沒有考慮過使用同一個IP的客戶端,所以我一定會添加它。但我很好奇1如何無效? – NukingDragons 2014-09-18 22:39:47

+0

如果您創建大小爲1的數組,則其中唯一的索引爲0,因爲索引從零開始。如果你有一個大小爲1的數組,那麼唯一有效的索引是[0]。如果你有一個大小爲2的數組,那麼有效索引是在[0]和[1]。 – 2014-09-18 22:44:42

+0

好的。我認爲如果我把1放進去,它會允許0和1,如果我把0放進去,它只會是0.所以我認爲我輸入的數字是它可以達到的最大值。感謝您指點我正確的方向 – NukingDragons 2014-09-18 22:48:02

相關問題