3

这是我的代码。

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <stdio.h>
#include <string.h>

int max(int socket_handle[]);

int main( void )
{
   int       max_clients_allowed = 2;
   int       socket_handle[max_clients_allowed];
   int       client_handle[max_clients_allowed];
   struct    sockaddr_in6 server_address[max_clients_allowed];
   struct    sockaddr_in6 client_address[max_clients_allowed];
   char      buffer[1000];
   socklen_t client_length;
   fd_set    read_handles;
   struct    timeval timeout_interval;
   int       bytes_received;
   int       port_number = 9000;
   int       retval;
   int       i;


   printf("Hello, human.\n");

   for (i = 0; i < max_clients_allowed; i++)
   {
       printf("Creating socket%d on port: %d\n", i, port_number + i);
       socket_handle[i] = socket(PF_INET6,SOCK_DGRAM,0);
       memset( &server_address[i], 0, sizeof( server_address[i] ) );
       server_address[i].sin6_family = AF_INET6;
       server_address[i].sin6_addr=in6addr_any;
       server_address[i].sin6_port=htons( port_number + i );

       if(bind( socket_handle[i], (struct sockaddr *)&server_address[i], sizeof( server_address[i] )) < 0)
       {
           perror("Unable to bind.");
           return -1;
       }
       else
       {
           printf("Bind %d successful.\n", i);
       }

   }



   while (1) {

       FD_ZERO(&read_handles);
       FD_SET(socket_handle[0], &read_handles);
       FD_SET(socket_handle[1], &read_handles);
       timeout_interval.tv_sec = 2;
       timeout_interval.tv_usec = 500000;
       retval = select(max(socket_handle) + 1, &read_handles, NULL, NULL, &timeout_interval);
       if (retval == -1)
       {
           printf("Select error\n");
           //error
       }
       else if ((retval = 0))
       {
           printf("timeout\n");
       }
       else
       {
           //good
           client_length = sizeof(struct sockaddr*);
           for (i = 0; i < max_clients_allowed; i++)
           {
              if (FD_ISSET(socket_handle[i], &read_handles))
              {
                  if((bytes_received = recvfrom(socket_handle[i],buffer,sizeof(buffer),0,(struct sockaddr *)&client_address[i], (socklen_t*)&client_length)) < 0)
                  {
                     perror("Error in recvfrom.");
                     break;
                  }
                  printf("\nData received:");
                  printf("\n--------------\n");
                  printf("%s", buffer);
            }
           }
       }
   }
}

int max(int socket_handle[])
{
    if (socket_handle[0] > socket_handle[1])
    {
        return socket_handle[0];
    }
        return socket_handle[1];
}

此代码应该绑定到端口 9000 和 9001。它们使用 select 查看哪些套接字有传入数据,然后打印消息。

我假设它与我的 recvfrom 函数有关。我已经尝试过使用参数但无济于事。

另一个问题可能是当我设置套接字时,我使用的是 sin6.addr = in6addr_any。我很确定 PF_INET6 和 AF_INET6 是正确的,但这也可能是一个问题。我一直在玩这个,但我找不到错误。如果有人能指出我的错误以便我修复它,我将不胜感激。我知道我即将完成这件事。

这是一道作业题,老师给了我们测试程序,它所做的只是在端口 9000 上发送一条消息。

4

1 回答 1

2

调用 时recvfrom(),您client_length在输入时将 设置为错误的值。它需要设置为sizeof(client_address[I])。您还需要在client_length每次调用时重置recvfrom()

当您打印 receivedbuffer时,您需要bytes_received考虑,因为缓冲区不会以空值结尾(除非客户端正在发送以空值结尾的数据)。

试试这个:

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <stdio.h>
#include <string.h>

int main( void )
{
    int       max_servers = 2;
    int       server_handle[max_servers];
    int       max_server_handle = 0;
    struct    sockaddr_in6 server_address[max_servers];
    struct    sockaddr_in6 client_address[max_servers];
    char      buffer[1000];
    socklen_t client_length;
    fd_set    read_handles;
    struct    timeval timeout_interval;
    int       bytes_received;
    int       port_number = 9000;
    int       retval;
    int       i;

    printf("Hello, human.\n");

    for (i = 0; i < max_servers; i++)
    {
        printf("Creating socket %d on port: %d\n", i, port_number + i);

        server_handle[i] = socket(PF_INET6, SOCK_DGRAM, 0);
        if (server_handle[i] < 0)
        {
            perror("Unable to create socket.");
            return -1;
        }

        if (server_handle[i] > max_server_handle)
            max_server_handle = server_handle[i];

        memset( &server_address[i], 0, sizeof( server_address[i] ) );
        server_address[i].sin6_family = AF_INET6;
        server_address[i].sin6_addr = in6addr_any;
        server_address[i].sin6_port = htons( port_number + i );

        if (bind( server_handle[i], (struct sockaddr *)&server_address[i], sizeof( server_address[i] )) < 0)
        {
            perror("Unable to bind.");
            return -1;
        }

        printf("Bind %d successful.\n", i);
    }

    while (1)
    {
        FD_ZERO(&read_handles);
        for (i = 0; i < max_servers; i++)
            FD_SET(server_handle[i], &read_handles);

        timeout_interval.tv_sec = 2;
        timeout_interval.tv_usec = 500000;

        retval = select(max_server_handle + 1, &read_handles, NULL, NULL, &timeout_interval);
        if (retval == -1)
        {
            printf("Select error\n");
            //error
        }
        else if (retval == 0)
        {
            printf("timeout\n");
        }
        else
        {
            //good
            for (i = 0; i < max_servers; i++)
            {
                if (FD_ISSET(server_handle[i], &read_handles))
                {
                    client_length = sizeof(client_address[i]);

                    if ((bytes_received = recvfrom(server_handle[i], buffer, sizeof(buffer), 0, (struct sockaddr *)&client_address[i], &client_length)) < 0)
                    {
                        perror("Error in recvfrom.");
                        break;
                    }

                    printf("\nData received on socket %d:", i);
                    printf("\n--------------\n");
                    printf("%.*s", bytes_received, buffer);
                }
            }
        }
    }
}
于 2013-03-07T00:36:01.737 回答