UDP-сервер и 2 UDP-клиента в C - PullRequest
       43

UDP-сервер и 2 UDP-клиента в C

0 голосов
/ 18 апреля 2011

Я прочитал руководство Биджа и создал UDP-сервер и клиента. Сначала я запускаю сервер, а затем запускаю 2 клиента. Сервер должен recevfrom клиент и sendto другой клиент. Когда клиент 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;  
}

Спасибо.

Ответы [ 2 ]

2 голосов
/ 18 апреля 2011

В начале 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()");
            }
        }
1 голос
/ 18 апреля 2011

В вашем коде есть следующее:

        // 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].Выглядит как ошибка для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...