UDP Server子进程无法发送

时间:2013-09-07 15:17:50

标签: c linux

我正在尝试使用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;
    }

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

2 个答案:

答案 0 :(得分:1)

问题最有可能发生在客户端:

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

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

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

答案 1 :(得分:0)

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