简体   繁体   中英

UDP Server child process can't send

I'm trying to create a chat program using UDP. I've created a parent and a child process in both the client and the server to separately receive and send messages. Problem is the server can't send. Help please. Here's my code.

CLIENT

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/stat.h>
    #include <arpa/inet.h>

    int main(int argc, char **argv)
    {
        int sockfd;
        struct sockaddr_in servaddr;
        socklen_t len = sizeof(servaddr);
        char mesg[1024], rmesg[1024];
        pid_t pid;

        if(argc!=2){ 
            printf("Usage: %s <ip_addr>\n",argv[0]);
            exit(1);
        }

        sockfd = socket(PF_INET,SOCK_DGRAM,0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(54321);
        inet_pton(AF_INET,argv[1],&servaddr.sin_addr);

        pid = fork();
        if(pid == 0) {
            printf("Type 'exit' to Exit. \n");
            while(1){
                fgets(mesg,sizeof(mesg),stdin);
                sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
                if(strcmp(mesg, "exit\n") == 0)
                    break;
            }
            close(sockfd);
            kill(pid, SIGINT);
            exit(0);
        }else{
            while(1){
                memset(rmesg,0,sizeof(rmesg));
                if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){
                    printf("From Server: %s", rmesg);
                }
            }
        }
        close(sockfd);
        return 0;
    }

SERVER

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/stat.h>
    #include <arpa/inet.h>

    int main(int argc, char **argv)
    {
        int sockfd1;
        struct sockaddr_in servaddr,cliaddr;
        socklen_t len = sizeof(cliaddr);
        char cli_ip[32];
        char mesg[1024], smesg[1024];
            pid_t  pid1;

        sockfd1 = socket(PF_INET,SOCK_DGRAM,0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(54321);
        inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip) );

        if ( bind( sockfd1, (struct sockaddr*) &servaddr, sizeof(servaddr) ) < 0 ){
            perror(NULL);
            exit(-1);
        }

        pid1 = fork();
        if(pid1 == 0){
            while(1){
                memset(mesg,0,sizeof(mesg));
                if( recvfrom(sockfd1,mesg,sizeof(mesg),0,(struct sockaddr *)&cliaddr,&len) > 0 ){
                    printf("From client: %s",mesg);
                }
            }
        }else{
            printf("Type 'exit' to Exit. \n");
            while(1){
                fgets(smesg,sizeof(smesg),stdin);
                sendto(sockfd1,smesg,strlen(smesg),0,(struct sockaddr *)&cliaddr,len);
                if(strcmp(smesg, "exit\n") == 0)
                    break;
            }
            close(sockfd1);
            kill(pid1, SIGINT);
            exit(0);
        }
        return 0;
    }

The problem is most likely in the client:

 while(1){ if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){ printf("From Server: %s", rmesg); } } 

You are calling recv on an unconnected socket . You're likely getting an error (probably ENOTCONN ) which you are ignoring. And I believe you're also seeing high CPU usage on the clients, since it is continuously looping, failing each system call.

The solution is to use recvfrom instead. Alternatively you can call connect on the socket, even if it is SOCK_DGRAM , but this is not normally done.

WHy are you using hte same socket for both server and client? This does not make sense. A simpler alternative would be to use two threads. One thread handling the server socket and the other thread handling the client thread. And ofcourse, you would need to have two sockets as well -- one for the server and one for the client. Also, the sendto() needs to have the address and port information of the receiver.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM