繁体   English   中英

UDP服务器子进程无法发送

[英]UDP Server child process can't send

我正在尝试使用UDP创建聊天程序。 我已经在客户端和服务器中创建了父进程和子进程,以分别接收和发送消息。 问题是服务器无法发送。 请帮助。 这是我的代码。

客户

    #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;
    }

服务器

    #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;
    }

该问题最有可能出现在客户端中:

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

您正在未连接的套接字上调用recv 您可能会遇到一个忽略的错误(可能是ENOTCONN )。 而且我相信您还会看到客户端上的CPU使用率很高,因为它不断循环,导致每个系统调用失败。

解决方案是改用recvfrom 或者,即使套接字是SOCK_DGRAM ,也可以在套接字上调用connect ,但是通常不这样做。

为什么在服务器和客户端上使用相同的套接字? 这根本不符合逻辑。 一个更简单的选择是使用两个线程。 一个线程处理服务器套接字,另一个线程处理客户端线程。 当然,您还需要有两个套接字-一个用于服务器,一个用于客户端。 同样,sendto()需要具有接收方的地址和端口信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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