昨天写的一篇关于UDP广播服务的小结,回头想了一下,有些错误,在此更正并总结。
之前,客户端接收不到服务器回复的原因是,客户端socket绑定到了广播地址上,而服务器在接收到广播包后,又将回复包发送到了recvfrom函数保存的客户端地址上,导致客户端在广播地址接收不到服务器的回复。
// Error Code for Server
if ((slen = recvfrom(sock, buf, 40, 0, (sockaddr *)&recvAddr, (socklen_t *)&rAddrLen)) > 0)
{
char sbuf[20] = "123456";
sendto(sock, sbuf, 20, 0, recvAddr, sizeof(recvAddr));
}
// Error Code for Client
sockaddr_in locAddr;
locAddr.sin_family = AF_INET;
locAddr.sin_port = htons(B_PORT);
locAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
if (-1 == bind(sock, (sockaddr *)&locAddr, sizeof(locAddr)))
{
return -1;
}
实际上,客户端只要绑定到本地地址INADDR_ANY就可以了,然后发送数据到广播地址,服务器端不必具有广播功能,其接收到客户端的广播包后,定向回复给客户端。
// Broadcast Server
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in locAddr;
locAddr.sin_family = AF_INET;
locAddr.sin_port = htons(B_PORT);
locAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (-1 == bind(sock, (sockaddr *)&locAddr, sizeof(locAddr)))
{
return -1;
}
while (1)
{
int slen;
char buf[40];
sockaddr_in recvAddr;
int rAddrLen = sizeof(recvAddr);
if ((slen = recvfrom(sock, buf, 40, 0, (sockaddr *)&recvAddr, (socklen_t *)&rAddrLen)) > 0)
{
char sbuf[20] = "123456";
sendto(sock, sbuf, 20, 0, recvAddr, sizeof(recvAddr));
}
else
{
continue;
}
}
}
// Broadcast Client
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int bl = 1;
if (-1 == setsockopt(sock, SOL_SOCKET, SO_BROADCAST, 0, &bl, (socklen_t *)sizeof(bl))
{
return -1;
}
sockaddr_in locAddr;
locAddr.sin_family = AF_INET;
locAddr.sin_port = htons(B_PORT);
locAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (-1 == bind(sock, (sockaddr *)&locAddr, sizeof(locAddr)))
{
return -1;
}
while (1)
{
printf("print Enter:");
getchar();
char sbuf[20] = "123456";
sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(B_PORT);
sendAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
sendto(sock, sbuf, 20, 0, sendAddr, sizeof(sendAddr));
while (1)
{
int slen;
char buf[40];
sockaddr_in recvAddr;
int rAddrLen = sizeof(recvAddr);
if ((slen = recvfrom(sock, buf, 40, 0, (sockaddr *)&recvAddr, (socklen_t *)&rAddrLen)) > 0)
{
printf("Recv Data From UDP Server\n");
}
else
{
continue;
}
}
}