接收单个发送的多个传入消息

时间:2014-12-18 21:18:08

标签: sockets visual-c++ udp winsock

我正在开发一个简单的UDP消息传递系统,而且我已经完成了它。该结构将有一个服务器,它只是简单地向所有在特定端口上侦听的客户端广播消息(它仅用于LAN或未连接到互联网的ad-hoc网络,尽管我的测试PC目前已插入网络)。我的问题是,每次发送消息时,客户端都会收到2份副本。目前我没有将目标IP设置为子网,所以这可能是问题所在:

(注意:我知道我违反了标准的客户端 - 服务器术语,因为我的“客户端”绑定了一个特定的端口,但请耐心等待。)

以下是我的服务器如何指定目标数据:

   d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

   if(d_socket == -1)
   {
      printf("\nError in creating socket");
      return false;
   }

   //socket option set to 1 because we are setting the SO_BROADCAST setting to true
   //MSDN says to use int for boolean option types.
   int l_socket_option = 1;

   setsockopt(d_socket, 
              SOL_SOCKET, 
              SO_BROADCAST, 
              (char*)&l_socket_option, 
              sizeof(int));

   //Zero out the broadcast address member to initialize it
   memset(&d_broadcast_address,
          0, 
          sizeof(d_broadcast_address));

   //Specify that 
   d_broadcast_address.sin_family = AF_INET;
   d_broadcast_address.sin_port = htons(34444);
   d_broadcast_address.sin_addr.s_addr = INADDR_BROADCAST;

我的客户端像这样打开端口:

d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

   //Set port so that calls to recvfrom do not block. Instead recvfrom returns an error if no data is present now.
   u_long l_no_block_specifier = 1;
   int l_socket_control_result = ioctlsocket(d_socket,
                                             FIONBIO,
                                             &l_no_block_specifier);

   if(d_socket == -1)
   {
      printf("\nError in creating socket");
      return false;
   }

   //Zero out the broadcast address member to initialize it
   memset(&d_server_address,
          0, 
          sizeof(d_server_address));

   //Specify that 
   d_server_address.sin_family = AF_INET;
   d_server_address.sin_port = htons(34444);
   d_server_address.sin_addr.s_addr = INADDR_ANY;

   d_address_length = sizeof(d_server_address);

   //Bind socket and print an error if bind fails.
   if ( bind(d_socket, (SOCKADDR*)&d_server_address, sizeof(SOCKADDR_IN)) != 0 )
   {
      printf("\nError in binding socket");
   }

打开端口后,客户端会生成一个线程来重复读取端口。我写了一个小测试应用程序,它只发送一个表示消息序列的整数。该计划的输出如下:

Sending message #0 at time = 4.0
Got message #0 at time = 4.0
Got message #0 at time = 25.0
Sending message #1 at time = 1004.0
Got message #1 at time = 1004.0
Got message #1 at time = 1047.0
Got message #2 at time = 2004.0
Sending message #2 at time = 2004.0
Got message #2 at time = 2064.0
Sending message #3 at time = 3005.0
Got message #3 at time = 3005.0
Got message #3 at time = 3086.0

我已经对它进行了相当彻底的测试,并确保程序本身不会意外地为每条消息打印出2个通知(除了时间戳显示2个收据之间迟来的到达)。

为什么会这样?我猜这是因为我的测试PC连接到互联网,因此广播将消息通过两条不同的路径传回我自己的PC。

修改

我更改了客户端,以便使用自己的IP地址绑定广播端口,而不是指定INADDR_ANY,这会停止重复的收据。我还更新了服务器,只在它所属的子网上进行广播,但我不认为这对多个收据有影响。

1 个答案:

答案 0 :(得分:0)

我更改了客户端,以便使用自己的IP地址绑定广播端口,而不是指定INADDR_ANY,这会停止重复的收据。我还更新了服务器,只在它所属的子网上进行广播,但我不认为这对多个收据有影响。 - 伊恩