首页 文章

套接字编程(客户端 - 服务器UDP)

提问于
浏览
0

我想构建一个客户端 - 服务器模型,对于连接到服务器的任意数量的客户端,服务器应该发送广播消息 . 下面是我实现的代码,它不会抛出任何错误,但我看不到服务器和客户端之间发生的任何通信 . 请告诉我,代码中的问题在哪里 .

我希望在客户端系统上看到从服务器传递的消息 .

/************* 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;
}

以下是客户端代码:

/************* 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;
}

1 回答

  • 0

    在高层次上,有一些事情需要解决 . 鉴于帖子中的代码有一个服务器,它启动与客户端的通信,需要修改行(以及相关代码)

    在服务器端:

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

    基本上这里发生的是udpSocket绑定到serverAddr,我们正在尝试发送到serverStorage(第二个参数) . 这里的问题是serverStorage没有绑定任何东西 . 基本上sendto有源权限但不是目的地 .

    在客户端:

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

    clientSocket没有绑定任何东西,因此系统会选择一个随机端口来监听它 . 在recvfrom调用中,第二个参数捕获另一方的地址详细信息 . 在代码中,您已将其绑定到服务器的IP和端口,但它没有任何效果,因为它由recvfrom调用填充并返回 .

    为了使事情在这里工作是我的建议(你可以添加细节,但已根据你发布的内容计算出骨架)

    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);
        }
        ..
    

    在客户端,这些方面的东西

    //..
        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;
    

    如果您将通信从客户端转换为服务器,则可以简化代码,从而消除客户端上固定端口号的需要 .

相关问题