2017-02-09 1 views
0

Je voudrais construire un modèle client - serveur où, pour n'importe quel nombre de clients connectés au serveur, le serveur devrait envoyer un message de diffusion. Ci-dessous le code que j'ai implémenté, il ne génère aucune erreur, mais je ne vois aucune communication entre le serveur et le client. S'il vous plaît laissez-moi savoir, où est le problème dans le code.Programmation de socket (client - serveur UDP)

J'aimerais voir le message transmis par le serveur sur le système client.

/************* UDP SERVER CODE *******************/ 

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]){ 
    int udpSocket, nBytes, buflen; 
    char buffer[1024]; 
    char string[1024]; 
    int portNum; 
    struct sockaddr_in serverAddr, clientAddr; 
    struct sockaddr_storage serverStorage; 
    socklen_t addr_size, client_addr_size; 
    int i; 

    /*Create UDP socket*/ 
    udpSocket = socket(AF_INET, SOCK_DGRAM, 0); 
    portNum=atoi(argv[1]); 
    /*Configure settings in address struct*/ 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(5000); 
    serverAddr.sin_addr.s_addr = inet_addr("192.168.1.117"); 

    memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 

    /*Bind socket with address struct*/ 
    int bStatus=bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 
    if (bStatus < 0) { 
     printf("error binding on server's port number\n"); 
     exit(1); 
    }  


    /*Initialize size variable to be used later on*/ 
    addr_size = sizeof serverStorage; 

memset(&clientAddr, 0, sizeof(clientAddr)); 
    clientAddr.sin_family = AF_INET; 
    clientAddr.sin_port = htons(portNum); // this is where client is bound 
    clientAddr.sin_addr.s_addr = inet_addr("192.168.1.114"); 

    while(1){ 
sprintf(buffer,"Hello Client"); 
    buflen=strlen(buffer); 
    int bytesSent = sendto(udpSocket,buffer,buflen,0,(struct sockaddr *)&clientAddr, sizeof(clientAddr)); 
    if (bytesSent < 0) { 
     printf("Error sending/ communicating with client\n"); 
     exit(1); 
    } 
    printf("%s\n",buffer); 

/* 
// **************************************************** 

memset(buffer, 0, 1024); 
buflen=65536; 
recvfrom(udpSocket,buffer,buflen,0,(struct sockaddr *)&serverStorage, &addr_size); 
printf("Received from server: %s\n",buffer); 

*/ 
} 

    return 0; 
} 

est Ci-dessous le code client:

 /************* UDP CLIENT CODE *******************/ 

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 

int main(int argc, char *argv[]){ 
    int clientSocket, portNum, nBytes, buflen; 
    char buffer[1024]; 
    char string[1024]; 
    struct sockaddr_in serverAddr,clientAddr; 
    socklen_t addr_size; 

    /*Create UDP socket*/ 
    clientSocket = socket(AF_INET, SOCK_DGRAM, 0); 
portNum = atoi(argv[1]); 
    /*Configure settings in address struct*/ 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(portNum); 
    serverAddr.sin_addr.s_addr = inet_addr("192.168.1.117"); 

// memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
memset(&serverAddr,0,sizeof(serverAddr)); 


// binding 
bind(clientSocket, (struct sockaddr *) &clientAddr, sizeof(clientAddr)); 


    /*Initialize size variable to be used later on*/ 
    addr_size = sizeof serverAddr; 

    while(1){ 

memset(buffer, 0, 1024); 
buflen=65536; 
recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size); 
//recvfrom(clientSocket,buffer,buflen,0,NULL,NULL); 
printf("Received from server: %s\n",buffer); 

/* 
//******************************************************************** 

sprintf(buffer,"Hello Client");  
buflen=strlen(buffer); 
sendto(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr,addr_size); 
printf("%s\n",buffer); 
*/ 
} 

return 0; 
} 
+0

ne devriez-vous pas vous «lier» à la réception? –

+2

"* UDP *", "* connecté *", hmmm? – alk

+0

@KevinDTimm n'est pas ce code C++ valide? –

Répondre

0

À un niveau élevé, il y a quelques choses qui doivent être pris en compte. Vu le code dans le message a un serveur qui initie la communication avec le client suivant la ligne doit être modifié (et le code connexes pour ces)

Du côté du serveur:

sendto(udpSocket,buffer,buflen,0,(struct sockaddr *)&serverStorage,addr_size); 

Essentiellement ce qui se passe ici est que udpSocket est lié à serverAddr et nous essayons d'envoyer à serverStorage (2ème dernier argument). Le problème ici est que serverStorage n'est lié à rien. Fondamentalement sendto a la source juste mais pas la destination.

Du côté client:

recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size); 

Le clientSocket est pas lié à quoi que ce soit pour que le système prend un port aléatoire où il écoutera. Dans l'appel recvfrom, l'argument 2nd 2nd capture les détails de l'adresse de l'autre côté. Alors que dans le code vous l'avez lié à l'adresse IP et au port du serveur, cela n'a aucun effet car il est rempli par l'appel recvfrom et renvoyé.

Pour faire fonctionner les choses ici est ce que je vous suggère (vous pouvez ajouter les détails mais qui ont travaillé sur le squelette de ce que vous avez publié)

server_initiating_with_client.c

//... 
    int udpSocket, nBytes, buflen; 
    char buffer[1024]; 
    int portNum; 
    struct sockaddr_in serverAddr, clientAddr; 
    struct sockaddr_storage serverStorage; 
    socklen_t addr_size, client_addr_size; 

    /*Create UDP socket*/ 
    udpSocket = socket(AF_INET, SOCK_DGRAM, 0); 
    portNum=atoi(argv[1]); 
    /*Configure settings in address struct*/ 
    memset(&serverAddr, 0, sizeof(serverAddr)); 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(5000); // Making sure server has a unique port number 
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    /*Bind socket with address struct*/ 
    int bStatus = bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 
    if (bStatus < 0) { 
     printf("error binding on server's port number\n"); 
     exit(1); 
    } 

    /*Initialize size variable to be used later on*/ 
    addr_size = sizeof serverStorage; 

    /* Because server is initiating the communication here one needs to set the 
    * clientAddr and needs to know the port number of the client 
    */ 
    memset(&clientAddr, 0, sizeof(clientAddr)); 
    clientAddr.sin_family = AF_INET; 
    clientAddr.sin_port = htons(portNum); 
    clientAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    while(1){ 
     sprintf(buffer,"Hello Client"); 
     buflen=strlen(buffer); 
     int bytesSent = sendto(udpSocket,buffer,buflen, 0, 
      (struct sockaddr *)&clientAddr, 
      sizeof(clientAddr)); 
     if (bytesSent < 0) { 
      printf("Error sending/ communicating with client\n"); 
      exit(1); 
     } 
      printf("Done sending %s\n", buffer); 
       sleep(1); 
    } 
    .. 

et sur la côté client quelque chose le long de ces lignes

//.. 
    int clientSocket, portNum, nBytes, buflen; 
    char buffer[1024]; 
    struct sockaddr_in serverAddr; 
    struct sockaddr_in clientAddr; 
    socklen_t addr_size; 

    /*Create UDP socket*/ 
    clientSocket = socket(PF_INET, SOCK_DGRAM, 0); 
    portNum = atoi(argv[1]); 
    /*Configure settings in address struct*/ 
    memset(&clientAddr, 0, sizeof(clientAddr)); 
    clientAddr.sin_family = AF_INET; 
    clientAddr.sin_port = htons(portNum); 
    clientAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    memset(&serverAddr, 0, sizeof(serverAddr)); 


    /*Bind on client side as well because you are specifically sending something over 
    * to the client. Usually the server will know where to talk back to the client 
    * but in your example because of the reversed semantics this will be needed 
    */ 

    bind(clientSocket, (struct sockaddr *) &clientAddr, sizeof(clientAddr)); 

    /*Initialize size variable to be used later on*/ 
    addr_size = sizeof serverAddr; 

    while(1){ 
     memset(buffer, 0, 1024); 
     buflen=65536; 
     recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size); 
     printf("Received from server: %s\n",buffer); 
     sleep(1); 
    } 
    return 0; 

le code peut être simplifiée si vous inversez votre comm du client au serveur, ce qui élimine la nécessité d'un fixe d numéro de port du côté client.

+0

Merci, @Aniruddh, pour l'explication et pour le code. En fonction de vos directives, j'ai modifié le code et mis à jour dans la section du code. L'aspect confus est qu'il ne communique toujours pas. – 034568

+0

Mis à jour un peu plus pour vous donner plus d'indices. Exécutez le programme avec un numéro de port autre que 5000 qui est là sur le côté serveur pour la liaison. Mais je vous suggère de repenser cela à partir du client communiquant avec le serveur. Les clients seront généralement nombreux et il n'est pas logique que le serveur connaisse le nombre de ports apriori des clients. Essentiellement, je recommande de commencer à envoyer au serveur sur un port bien connu, mais sur le côté client ne liant à rien. Le serveur devrait alors lire le recvfrom et communiquer sur la même adresse. Bonne chance –