我正在开发一个简单的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,这会停止重复的收据。我还更新了服务器,只在它所属的子网上进行广播,但我不认为这对多个收据有影响。
答案 0 :(得分:0)
我更改了客户端,以便使用自己的IP地址绑定广播端口,而不是指定INADDR_ANY,这会停止重复的收据。我还更新了服务器,只在它所属的子网上进行广播,但我不认为这对多个收据有影响。 - 伊恩