Mac C++ Broadcast -> 不止一个网络接口
Mac C++ Broadcast -> more then one network-interface
我的 mac 上有一个广播程序,一切正常,但如果我有一个以上的网络接口,他什么也收不到。
所以我现在要做的是:
检查 mac
上哪些网络接口处于活动状态
向每个活动界面发送广播(所以我必须select我想使用哪个界面)
收到答案(如果有的话:))
有趣:
广播客户端在我的 WLAN 上(设备之间有一个路由器),我的 LAN 上有正常的互联网连接。如果我在系统配置中停用 LAN,他也没有找到我的其他设备,但是如果我拔出电缆他找到了其他设备......所以也许我不必查看哪个接口处于活动状态并且有一个查看连接到哪个接口。
你有一些建议或好的 google 关键字让我这样做吗?
很久以前,但如果有人找到我的 post,这是我的解决方案:
#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while ((shift >= 0) && (*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char)atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
int Broadcast::BroadcastToAllInterfaces()
{
DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
globalDatabase->SetInBroadcast();
moreThenOne = 0;
#if defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while (p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
addr << dstAddrStr;
descss << p->ifa_name;
descss >> descs;
addr >> addrs;
DoABroadcast(dstAddr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it STILL_RUN
ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while ((next) && (name == NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while (ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
int setUnnamed = 0;
if (name == NULL)
{
sprintf(buf, "unnamed");
name = buf;
setUnnamed = 1;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
if (setUnnamed == 0)
{
addr << dstAddrStr;
descss << desc;
descss >> descs;
addr >> addrs;
DoABroadcast(baddr);
}
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
globalDatabase->SetLeaveBroadcast();
return 1;
}
int Broadcast::DoABroadcast(uint32 broadAddr)
{
int askSinlen = sizeof(struct sockaddr_in);
int askBuflen = MAXBUF;
int message;
char buf[512];
int status;
char askBuffer[MAXBUF];
struct sockaddr_in sock_in, client_adress, client_adress2;
#ifdef __APPLE__
socklen_t clientLength;
int askYes = 1;
#else
char askYes = 1;
int clientLength;
WSADATA w;
int result = WSAStartup(MAKEWORD(2, 2), &w);
#endif
int recSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (recSocket <0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(4028);
sock_in.sin_family = PF_INET;
client_adress.sin_family = PF_INET;
client_adress.sin_port = htons(4029);
client_adress.sin_addr.s_addr = htonl(broadAddr);
askSinlen = sizeof(sock_in);
client_adress2.sin_family = AF_INET;
client_adress2.sin_port = htons(4028);
client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);
status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");
status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
fd_set fds;
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(recSocket, &fds);
int ret;
if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
{
int e = 0;
while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
{
clientLength = sizeof(client_adress2);
message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);
if (message == -1)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -5;
}
else
{
std::string hereisyourbroadcast(buf);
}
}
}
else
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -6;
}
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 1;
}
我的 mac 上有一个广播程序,一切正常,但如果我有一个以上的网络接口,他什么也收不到。
所以我现在要做的是:
检查 mac
上哪些网络接口处于活动状态向每个活动界面发送广播(所以我必须select我想使用哪个界面)
收到答案(如果有的话:))
有趣: 广播客户端在我的 WLAN 上(设备之间有一个路由器),我的 LAN 上有正常的互联网连接。如果我在系统配置中停用 LAN,他也没有找到我的其他设备,但是如果我拔出电缆他找到了其他设备......所以也许我不必查看哪个接口处于活动状态并且有一个查看连接到哪个接口。
你有一些建议或好的 google 关键字让我这样做吗?
很久以前,但如果有人找到我的 post,这是我的解决方案:
#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while ((shift >= 0) && (*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char)atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
int Broadcast::BroadcastToAllInterfaces()
{
DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
globalDatabase->SetInBroadcast();
moreThenOne = 0;
#if defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while (p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
addr << dstAddrStr;
descss << p->ifa_name;
descss >> descs;
addr >> addrs;
DoABroadcast(dstAddr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it STILL_RUN
ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while ((next) && (name == NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while (ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
int setUnnamed = 0;
if (name == NULL)
{
sprintf(buf, "unnamed");
name = buf;
setUnnamed = 1;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
if (setUnnamed == 0)
{
addr << dstAddrStr;
descss << desc;
descss >> descs;
addr >> addrs;
DoABroadcast(baddr);
}
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
globalDatabase->SetLeaveBroadcast();
return 1;
}
int Broadcast::DoABroadcast(uint32 broadAddr)
{
int askSinlen = sizeof(struct sockaddr_in);
int askBuflen = MAXBUF;
int message;
char buf[512];
int status;
char askBuffer[MAXBUF];
struct sockaddr_in sock_in, client_adress, client_adress2;
#ifdef __APPLE__
socklen_t clientLength;
int askYes = 1;
#else
char askYes = 1;
int clientLength;
WSADATA w;
int result = WSAStartup(MAKEWORD(2, 2), &w);
#endif
int recSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (recSocket <0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(4028);
sock_in.sin_family = PF_INET;
client_adress.sin_family = PF_INET;
client_adress.sin_port = htons(4029);
client_adress.sin_addr.s_addr = htonl(broadAddr);
askSinlen = sizeof(sock_in);
client_adress2.sin_family = AF_INET;
client_adress2.sin_port = htons(4028);
client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);
status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");
status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
fd_set fds;
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(recSocket, &fds);
int ret;
if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
{
int e = 0;
while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
{
clientLength = sizeof(client_adress2);
message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);
if (message == -1)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -5;
}
else
{
std::string hereisyourbroadcast(buf);
}
}
}
else
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -6;
}
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 1;
}