C中的UDP服务器和2个UDP客户端

| 我阅读了Beej的指南,并创建了UDP服务器和客户端。我首先运行服务器,然后运行2个客户端。服务器应该“ 0”个客户端,“ 1”个其他客户端。当客户端1发送东西时,客户端0接收它。当客户端0发送某些内容时,客户端1不会收到它。谁能看到代码有什么问题吗?我已经阅读了有关UDP,C,服务器,聊天的所有问题,但找不到任何可以帮助我的东西。我正在OSX上编译此代码。任何帮助表示赞赏。以下是服务器代码:
 #include <arpa/inet.h>  
 #include <netinet/in.h>  
 #include <stdio.h>  
 #include <sys/types.h>  
 #include <sys/socket.h>  
 #include <unistd.h>  
 #include <stdlib.h>  
 #include <string.h>  
 #define BUFLEN 512  
 #define PORT 7777  

 void err(char *str)  
 {  
     perror(str);  
     exit(1);  
 }  

 int main(void)  
 {  
     struct sockaddr_in my_addr, cli_addr[2],cli_temp;  
     int sockfd;  
     socklen_t slen[2],slen_temp;
     slen[1]=sizeof(cli_addr[1]); 
     slen[2]=sizeof(cli_addr[2]);
     slen_temp = sizeof(cli_temp);
     char buf[BUFLEN];  
     int clients = 0;
     int client_port[2];

     if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
     {
         printf(\"test\\n\");
         err(\"socket\");  
     }else{  
         printf(\"Server : Socket() successful\\n\");  
     }   
     bzero(&my_addr, sizeof(my_addr));  
     my_addr.sin_family = AF_INET;  
     my_addr.sin_port = htons(PORT);  
     my_addr.sin_addr.s_addr = htonl(INADDR_ANY);  

     if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)
     {
         err(\"bind\");  
     }else{
         printf(\"Server : bind() successful\\n\");  
     }

     while(1)  
     {
         //receive
         printf(\"Receiving...\\n\");
         if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_temp, &slen_temp)==-1)  
             err(\"recvfrom()\");
         if (clients==0) {
             //first connection
             //store the temp connection details to the array
             cli_addr[0] = cli_temp;
             //get client 0 port
             client_port[0] = ntohs(cli_addr[0].sin_port);
             clients++;
             printf(\"Client 0 connected. Port: %d\\n\",client_port[0]);
             sendto(sockfd, \"You are the only client.\", 24, 0, (struct sockaddr*)&cli_temp, slen_temp);
         }else if (clients==1) {
             //new or existing
             if (client_port[0]==ntohs(cli_temp.sin_port)) {
                 //send back to client 0 that nobody else connected yet
                 sendto(sockfd, \"You are the only client.\", 24, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
                 printf(\"Only client\\n\");
             }else{
                 //new connection
                 cli_addr[1] = cli_temp;
                 client_port[1] = ntohs(cli_addr[1].sin_port);
                 clients++;
                 printf(\"GOt second client\\n\");
                 sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
             }
        }else{
            //there are 2 clients connected here. If we get an error from the sendto then we decrement clients
            if (client_port[0]==ntohs(cli_temp.sin_port)) {
                //client 0 talking send to client 1
                printf(\"Sedning message to client 1\\n\");
                if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
                {
                    clients--;
                    err(\"sendto()\");
                }
            }else {
                //client 1 talking send to client 0
                printf(\"Sending message to client 0\\n\");
                if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
                {
                    clients--;
                    err(\"sendto()\");
                }
            }

        }
        //printf(\"Received packet from %s:%d\\nData: %s\\n\",  
        //        inet_ntoa(cli_addr[clients].sin_addr), ntohs(cli_addr[clients].sin_port), buf);  
     }  

     close(sockfd);  
     return 0;  
}
和客户:
#include <arpa/inet.h>  
#include <netinet/in.h>  
#include <stdio.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#define BUFLEN 512  
#define PORT 7777  

void err(char *s)  
{  
    perror(s);  
    exit(1);  
}  
sig_atomic_t child_exit_status;

void clean_up_child_process (int signal_number) 
{
    /* Clean up the child process. */ 
    int status; 
    wait (&status); 
    /* Store its exit status in a global variable. */ 
    child_exit_status = status;
}
 int main(int argc, char** argv)  
 {  
     struct sockaddr_in serv_addr;  
     int sockfd, slen=sizeof(serv_addr);  
     char buf[BUFLEN];  
     struct sigaction sigchld_action; 
     memset (&sigchld_action, 0, sizeof (sigchld_action)); 
     sigchld_action.sa_handler = &clean_up_child_process; 
     sigaction (SIGCHLD, &sigchld_action, NULL);
     int pid,ppid;

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

     if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)  
         err(\"socket\");  

     bzero(&serv_addr, sizeof(serv_addr));  
     serv_addr.sin_family = AF_INET;  
     serv_addr.sin_port = htons(PORT);  
     if (inet_aton(argv[1], &serv_addr.sin_addr)==0)  
     {  
         fprintf(stderr, \"inet_aton() failed\\n\");  
         exit(1);  
     }
     pid = fork();
     if (pid<0) {
         err(\"Fork Error\");
     }else if (pid==0) {
         //child process will receive from server
         while (1) {
             bzero(buf,BUFLEN);
             printf(\"Attempting to READ to socket %d: \",sockfd);
             fflush(stdout);
             //recvfrom here
             if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, &slen)==-1)  
                 err(\"recvfrom()\");

             printf(\"The message from the server is: %s \\n\",buf);
             if (strcmp(buf,\"bye\\n\") == 0) {
                 ppid = getppid();
                 kill(ppid, SIGUSR2);

                 break;
             }
         }
     }else {
         //parent will send to server
         while(1){
             printf(\"Please enter the message to send: \");
             bzero(buf,BUFLEN);
             fgets(buf,BUFLEN,stdin);
             printf(\"Attempting to write to socket %d: \",sockfd);
             fflush(stdout);
             //send to here
             if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, slen)==-1)
             {
                 err(\"sendto()\");
             }
         }
     }
     close(sockfd);  
     return 0;  
}
谢谢。     
已邀请:
在代码中,您具有以下内容:
        // there are 2 clients connected here. If we get an error from the sendto
        // then we decrement clients
        if (client_port[0]==ntohs(cli_temp.sin_port)) {
            //client 0 talking send to client 1
            printf(\"Sedning message to client 1\\n\");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
            {
                clients--;
                err(\"sendto()\");
            }
        }else {
            //client 1 talking send to client 0
            printf(\"Sending message to client 0\\n\");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
            {
                clients--;
                err(\"sendto()\");
            }
        }
请注意,两个部分(1到0以及0到1)都发送到
&cli_addr[1]
。对我来说似乎是个虫子。     
在main开头,您已获得以下代码:
 struct sockaddr_in my_addr, cli_addr[2],cli_temp;  
 int sockfd;  
 socklen_t slen[2],slen_temp;
 slen[1]=sizeof(cli_addr[1]); 
 slen[2]=sizeof(cli_addr[2]);
这应该更改为:
 struct sockaddr_in my_addr, cli_addr[2],cli_temp;  
 int sockfd;  
 socklen_t slen[2],slen_temp;
 slen[0]=sizeof(cli_addr[0]); 
 slen[1]=sizeof(cli_addr[1]);
我浏览了其余代码,没有看到其他错误。我不确定这是否可以解决您的问题,但这绝对是错误的。 (您可能知道这一点,但是)这是错误的,因为数组的第一个元素是
array[0]
,而不是
array[1]
,因此,如果您有一个包含2个元素的数组,则
array[2]
将不存在。 更新资料 更改
else {
            //client 1 talking send to client 0
            printf(\"Sending message to client 0\\n\");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
            {
                clients--;
                err(\"sendto()\");
            }
        }
else {
            //client 1 talking send to client 0
            printf(\"Sending message to client 0\\n\");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[1])==-1)
            {
                clients--;
                err(\"sendto()\");
            }
        }
    

要回复问题请先登录注册