2017-01-09 3 views
1

J'essaie d'exécuter ce programme client serveur simple en utilisant winsock. Le serveur accepte la connexion des clients, mais ne peut pas recevoir les envois de données client. Je me bats pour trouver le problème.Winsock simple Client Server, réception échoue

SERVEUR:

#define _WINSOCK_DEPRECATED_NO_WARNINGS 

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

#pragma comment(lib,"ws2_32.lib") 

#define DEFAULT_PORT 18000 

int main(int argc, char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET s, new_socket; 
    struct sockaddr_in server, client; 
    char *message, client_msg[2000]; 
    int port, c, recv_size; 

    if (argc > 2) 
    { 
     std::cout << "usage : " << argv[1] << " <PORT>\n"; 
     std::cout << "If no port is given then default port is used.\n"; 
     std::cout << "DEFAULT PORT : 18000\n"; 
     return 1; 
    } 
    if (argc == 2) 
    { 
     port = atoi(argv[2]); 
    } 
    else 
    { 
     port = DEFAULT_PORT; 
    } 

    std::cout << "Initializing Winsock..."; 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     std::cout << "Failed. Error code" << WSAGetLastError(); 
     return 1; 
    } 
    std::cout << "Initialized.\n\n"; 

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
    { 
     std::cout << "Could not create Socket : " << WSAGetLastError() << "\n"; 
     return 1; 
    } 
    std::cout << "Socket Created.\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 << "Bind failed with error code : " << WSAGetLastError() << "\n"; 
    } 
    std::cout << "Bind done.\n"; 


    listen(s, 3); 

    std::cout << "Waiting for incoming connections...\n"; 

    while (true) 
    { 
     c = sizeof(struct sockaddr_in); 

     new_socket = accept(s, (struct sockaddr*)&client, &c); 
     if (new_socket == INVALID_SOCKET) 
     { 
      closesocket(new_socket); 
      std::cout << "Accept failed with error code : " << WSAGetLastError() << "\n"; 
     } 
     else 
     { 
      std::cout << "Connection accepted.\n"; 

      if ((recv_size = recv(s, client_msg, 200, 0)) == SOCKET_ERROR) 
      { 
       closesocket(new_socket); 
       std::cout << "Receive Failed.\n\n"; 
      } 
      else 
      { 
       if (strcmp(client_msg, "PASSWD")) 
       { 
        message = "HELLO!"; 
        send(new_socket, message, strlen(message), 0); 
       } 
       else 
       { 
        message = "Authentication failed!"; 
        send(new_socket, message, strlen(message), 0); 
        closesocket(new_socket); 
       } 
      } 
     } 
    } 

    closesocket(s); 
    WSACleanup(); 


    return 0; 
} 

CLIENT:

#define _WINSOCK_DEPRECATED_NO_WARNINGS 

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

#pragma comment(lib,"ws2_32.lib") 

#define DEFAULT_SERVER "127.0.0.1" 
#define DEFAULT_PORT 18000 
#define PASSWORD "PASSWD" 

int main(int argc, char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET s; 
    struct sockaddr_in server; 
    char *message, server_reply[2000], *server_addr; 
    int recv_size, port = DEFAULT_PORT; 

    if (argc > 4) 
    { 
     std::cout << "usage : " << argv[0] << " <Server IP> <Server Port> [DATA]\n\n"; 
     std::cout << "If any argument is missing, default values will be used.\n"; 
     std::cout << "Default Address : localhost (127.0.0.1)\nDefault Port : 18000\nDefault DATA: 'PASSWD'\n\n"; 
     return 1; 
    } 
    else if (argc == 4) 
    { 
     server_addr = argv[1]; 
     port = atoi(argv[2]); 
     message = argv[3]; 
    } 
    else if (argc == 3) 
    { 
     server_addr = argv[1]; 
     port = atoi(argv[2]); 
     message = PASSWORD; 
    } 
    else if (argc == 2) 
    { 
     server_addr = argv[1]; 
     port = DEFAULT_PORT; 
     message = PASSWORD; 
    } 
    else 
    { 
     server_addr = DEFAULT_SERVER; 
     port = DEFAULT_PORT; 
     message = PASSWORD; 
     //server_addr = "127.0.0.1"; 
     //port = 2222; 
     //message = "HELLO"; 
    } 

    std::cout << "Initialising Winsock..\n"; 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     std::cout << "Failed.. Error Code : " << WSAGetLastError() << "\n"; 
     return 1; 
    } 
    std::cout << "Winsock Initialised.\n"; 

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
    { 
     std::cout << "Could not create socket : " << WSAGetLastError() << "\n"; 
    } 
    std::cout << "Socket Created.\n"; 

    server.sin_addr.s_addr = inet_addr(server_addr); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(port); 

    if (connect(s, (struct sockaddr*)&server, sizeof(server)) < 0) 
    { 
     std::cout << "Could not connect to " << server_addr << " on port " << port << ".\n"; 
     WSACleanup(); 
     return 1; 
    } 
    std::cout << "Connected to " << server_addr << " on port " << port << ".\n\n"; 

    if (send(s, message, strlen(message), 0) < 0) 
    { 
     std::cout << "Sending Data failed.\n"; 
     WSACleanup(); 
     return 1; 
    } 
    std::cout << "Data send.\n\n"; 

    //Sleep(500); 

    if ((recv_size = recv(s, server_reply, 20, 0)) == SOCKET_ERROR) 
    { 
     std::cout << "Receive Failed.\n\n"; 
    } 
    else 
    { 


     server_reply[recv_size] = '\0'; 

     std::cout << server_addr << " : " << server_reply << "\n"; 

    } 
    //Sleep(5000); 

    closesocket(s); 
    WSACleanup(); 

    return 0; 
} 

Toute aide serait appréciée. Merci.

+1

Un problème est que strcmp() attend une chaîne terminée par zéro, ce qui n'est pas ce que vous lui avez fourni. En dehors de cela, nous ne serons pas en mesure d'aider à moins que vous expliquiez * exactement * ce qui ne va pas - obtenez-vous une erreur, est-ce que le recv ne revient jamais, ou quoi? –

+0

Désolé, mon code est mal formaté sans beaucoup de commentaires. Je mettrai des commentaires si nécessaire après la fin du mandat. Exactement ce que j'essaie de faire est: Le serveur écoute sur un port, les clients se connectent et le premier message qu'ils envoient est une clé secrète en texte brut. Le serveur reçoit le message et maintient la connexion ouverte si la clé correspond ou la ferme. Mon plan est d'ajouter des threads pour plusieurs connexions plus tard et de les mettre à l'échelle dans un système de répartition d'événements. Plus tard, ajoutez pi de framboise dans l'installation et faites un simple Hub IOT de zéro. – windlessStorm

+0

Je n'ai pas demandé ce que vous essayez de faire, j'ai demandé ce qui n'allait pas. Mais je pense que Jun a trouvé le problème principal - le serveur essaie de lire depuis 's' alors qu'il devrait lire' new_socket'. –

Répondre

1

if ((recv_size = recv (s, client_msg, 200, 0)) == SOCKET_ERROR)

changement s à new_socket dans votre code côté serveur.

+0

Merci, cela fonctionne maintenant. Je pensais que le message est reçu sur le port spécifique des serveurs, donc le serveur devrait écouter son propre socket. J'aurais dû lire plus sur recv. – windlessStorm