2013-03-07 64 views
3

这是我的代码。C - 使用select在多个端口上侦听的简单ipv6 udp服务器。从一个端口接收消息,而不是另一个

#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是正确的,但这也可能是一个问题。我一直在玩这个,但是我找不到这个bug。如果有人能指出我的错误,我会很感激,所以我可以修复它。我知道我正在完成这项工作。

这是一个家庭作业的问题,老师给我们的测试程序和它的作用仅仅是在端口发送一个消息9000

+0

请在这里展示你的代码 - pastebin.com超载,不会让我看看。 – Barmar 2013-03-07 00:35:21

+1

Pastebin现在正在关闭。请删除您的代码,以证明您的问题,然后编辑您的问题以显示实际代码。 – 2013-03-07 00:35:28

+0

@Barmer代码复制/粘贴在这里 – 2013-03-07 00:44:41

回答

2

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

打印收到的buffer时,由于缓冲区不会以空值终止(除非客户端正在发送以空值终止的数据),因此您需要考虑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); 
       } 
      } 
     } 
    } 
} 
+0

我的错误。我有ipv​​6版本。 – 2013-03-07 00:44:23

+0

除了底部的printf语句之外,当我认为完成了这一点之前,这就是我所做的,在所有的摆弄之前。它不会给我任何错误。这是输出: 数据接收:\ n -------------- \ n 已发送到端口9000 \ n 数据接收:\ n ------ -------- \ n “发送到端口9000”是从客户端发送的消息。它也应该说“发送到端口9001”。所以,recv函数都是成功的,但是我没有得到消息的字符串。 Wireshark显示这两个数据包都是有效的。编辑:我希望我可以在这里把换行符.. – 2013-03-07 01:49:47

+0

我已经通过它。它不工作。我从你的代码镜像的唯一东西是这一行“printf(”%。* s“,bytes_received,buffer);”谢谢您的帮助! :] – 2013-03-07 05:40:22

相关问题