2017-01-08 3 views
0

Ich habe ein Problem mit der Serververbindung. Wenn ich versuche, den Server an die IP-Adresse meines externen Geräts zu binden, habe ich einen Winsock-Fehler erhalten: 10049 Die angeforderte Adresse kann nicht zugewiesen werden. Die Verwendung von localhost Server funktioniert ordnungsgemäß. Diese IP-Adresse: 192.168.0.202 Ping erfolgreich. Ich arbeitete an win8.1. Ich habe Firewall und Windows Defender ausgeschaltet und es hat nicht geholfen.Winsock Fehler 10049 versucht zu binden

Code mit Server-Implementierung wurde von http://www.planetchili.net/forum/viewtopic.php?f=3&t=3433

#include "Server.h" 

Server::Server(int PORT, bool BroadcastPublically) //Port = port to broadcast on. BroadcastPublically = false if server is not open to the public (people outside of your router), true = server is open to everyone (assumes that the port is properly forwarded on router settings) 
{ 
    //Winsock Startup 
    WSAData wsaData; 
    WORD DllVersion = MAKEWORD(2, 1); 
    if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup. 
    { 
     MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR); 
     exit(1); 
    } 


    addr.sin_addr.s_addr = inet_addr("192.168.0.202"); 
    addr.sin_port = htons(1234); //Port 
    addr.sin_family = AF_INET; //IPv4 Socket 

    sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections 
    if (bind(sListen, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) //Bind the address to the socket, if we fail to bind the address.. 
    { 
     std::string ErrorMsg = "Failed to bind the address to our listening socket. Winsock Error:" + std::to_string(WSAGetLastError()); 
     MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR); 
     exit(1); 
    } 
    if (listen(sListen, SOMAXCONN) == SOCKET_ERROR) //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections, if we fail to listen on listening socket... 
    { 
     std::string ErrorMsg = "Failed to listen on listening socket. Winsock Error:" + std::to_string(WSAGetLastError()); 
     MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR); 
     exit(1); 
    } 
    serverptr = this; 
} 

bool Server::ListenForNewConnection() 
{ 
    SOCKET newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection 
    if (newConnection == 0) //If accepting the client connection failed 
    { 
     std::cout << "Failed to accept the client's connection." << std::endl; 
     return false; 
    } 
    else //If client connection properly accepted 
    { 
     std::cout << "Client Connected! ID:" << TotalConnections << std::endl; 
     Connections[TotalConnections] = newConnection; //Set socket in array to be the newest connection before creating the thread to handle this client's socket. 
     CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandlerThread, (LPVOID)(TotalConnections), NULL, NULL); //Create Thread to handle this client. The index in the socket array for this thread is the value (i). 
     //std::string MOTD = "MOTD: Welcome! This is the message of the day!."; 
     //SendString(TotalConnections, MOTD); 
     TotalConnections += 1; //Incremenent total # of clients that have connected 
     return true; 
    } 
} 

bool Server::ProcessPacket(int ID, Packet _packettype) 
{ 
    switch (_packettype) 
    { 
    case P_ChatMessage: //Packet Type: chat message 
    { 
     std::string Message; //string to store our message we received 
     if (!GetString(ID, Message)) //Get the chat message and store it in variable: Message 
      return false; //If we do not properly get the chat message, return false 
          //Next we need to send the message out to each user 
     for (int i = 0; i < TotalConnections; i++) 
     { 
      if (i == ID) //If connection is the user who sent the message... 
       continue;//Skip to the next user since there is no purpose in sending the message back to the user who sent it. 
      if (!SendString(i, Message)) //Send message to connection at index i, if message fails to be sent... 
      { 
       std::cout << "Failed to send message from client ID: " << ID << " to client ID: " << i << std::endl; 
      } 
     } 
     //std::cout << "Processed chat message packet from user ID: " << ID << std::endl; 

     if(Message == "go") 
      std::cout << "MESSAGE:GO!" << std::endl; 
     else if(Message == "left") 
      std::cout << "MESSAGE: GO LEFT!" << std::endl; 
     else if (Message == "right") 
      std::cout << "MESSAGE:GO RIGHT!" << std::endl; 
     else 
      std::cout << "MESSAGE:DO NOTHING!" << std::endl; 
     break; 
    } 

    default: //If packet type is not accounted for 
    { 
     std::cout << "Unrecognized packet: " << _packettype << std::endl; //Display that packet was not found 
     break; 
    } 
    } 
    return true; 
} 

void Server::ClientHandlerThread(int ID) //ID = the index in the SOCKET Connections array 
{ 
    Packet PacketType; 
    while (true) 
    { 
     if (!serverptr->GetPacketType(ID, PacketType)) //Get packet type 
      break; //If there is an issue getting the packet type, exit this loop 
     if (!serverptr->ProcessPacket(ID, PacketType)) //Process packet (packet type) 
      break; //If there is an issue processing the packet, exit this loop 
    } 
    std::cout << "Lost connection to client ID: " << ID << std::endl; 
    closesocket(serverptr->Connections[ID]); 
    return; 
} 

Irgendwelche Ideen ergriffen?

+0

Hier gibt es keinen Verbindungsschritt. Dies ist ein Server. Es bindet und akzeptiert. Unklar, was du verlangst. – EJP

+1

Die bedingte Anweisung, wo Sie an 'INADDR_ANY' vs' 192.168.0.202' binden, tut nicht, was Sie denken, dass es tut. Generell sollten Sie immer an INADDR_ANY binden. Wenn Sie versuchen, die Konnektivität auf einen IP-Adressbereich zu beschränken, müssen Sie entweder nach dem Akzeptieren des Anrufs mit dem Problem umgehen oder eine Firewall-Regel verwenden, um unerwünschte Verbindungen zu blockieren. – selbie

+0

@EPJ Es wurde nicht gebunden. Ich habe einen Fehler erhalten "Fehler beim Verbinden der Adresse mit unserem hörenden Socket. Winsock Fehler: 10049" – newblack

Antwort

3

Die Funktion bind() wird verwendet, um anzugeben, welche Adresse des Serversystems verwendet wird, um Verbindungen von fernen Clients zu akzeptieren, nicht um anzugeben, welcher ferne Client eine Verbindung zum Server herstellen darf. Die bind()-Funktion kann nur mit Adressen verwendet werden, die für den Server selbst gültig sind, nicht für Adressen von Remote-Geräten oder Hosts.

Um zu begrenzen, welcher Remote-Host eine Verbindung zu Ihrem Server herstellen darf, müssen Sie die Verbindung akzeptieren und die Remote-Adresse zu diesem Zeitpunkt validieren. Wenn die Adresse nicht die richtige ist, ist die Verbindung geschlossen.

Im Allgemeinen möchten Sie INADDR_ANY verwenden, es sei denn, Ihr Server ist multi-homed (mehr als eine physische Verbindung zu mehr als einem Netzwerk), und nur dann, wenn Sie versuchen, Verbindungen zu einem der Netzwerke zu beschränken Server ist angeschlossen.

+0

@Paulina Sie erhalten den gleichen Fehler beim 'listen()' Anruf? –

+0

Nein, tut mir leid mein falult.Still bind() -Funktionsfehler; ( Ich habe den Code bearbeitet. Was, wenn ich nur mit dieser externen Maschine IP verbinden möchte? – newblack

+1

@Paulina die Verbindung akzeptieren und die Remote-Adresse überprüfen. Wenn es nicht übereinstimmt, schließen Sie den Sockel und warte auf die nächste Verbindung. –

0

Winsock gibt das Fehlerflag 10049 (WSAEADDRNOTAVAIL) über seine API WSAGetLastError zurück, wenn eine Anwendung versucht, eine Verbindung mit einer ungültigen IP-Adresse herzustellen.

Bindung an eine bestimmte IP-Adresse bedeutet, dass, wenn Sie das Programm (Server) ausführen, die Adresse gültig (verfügbar) sein sollte, aber DHCP gibt Ihnen dynamische IP-Adressen jedes Mal trennen Sie/verbinden Sie Ihren Adapter, so dass Sie die Adresse gebunden Server die vorherige Zeit nicht gültig ist, sie zu korrigieren, öffnen Sie cmd ein und geben ein:

ipconfig 

Sie die Liste der IP4 bekommen/ip6 wendet sich dann an Sie einen von ihnen auswählen können und binden Sie Ihre Server jedoch ist diese Methode wirklich langweilig, so die Alternative ist, an INADDR_ANY zu binden, damit Sie das System die Arbeit für Sie erledigen lassen.

Sie müssen nur vom Client die Serveradresse und Port eingeben und verbinden.