UDP多网卡广播附源码

xingyun86 2020-7-27 1028

  udp可以进行广播,但是有多个网卡的时候如何让多个网卡同时发送广播?有人说在bind的时候,指定“addrClient.sin_addr.s_addr = INADDR_ANY”,但是这样就真的行了吗?如果有人测试后就会发现这样依然不是所有的网卡同时发送广播,下面给出了一种方式,主要是采用每一个网卡绑定一个socket,然后每个socket都同时进行广播;

    如果不清楚udp单网卡如何通讯的,不知道服务器的代码怎么弄的可以给我留言,谢谢!

    方便他人亦是方便自己,如果觉得还行就点下赞吧,这样可以帮助其他人更快的找到解决问题的方法;有疑问的也可留言哦, 谢谢!

    源代码链接: https://pan.baidu.com/s/1rblrwzP_bK5HCNfMyGVwfQ 提取码: nwus

客户端完整代码:

#include <stdio.h>
#include <winsock.h>
#include <time.h>
#pragma comment(lib,"ws2_32.lib")
DWORD WINAPI ThreadProc(_In_  LPVOID lpParameter)
{
char szIp[16] = {0};
strcpy (szIp, (char*)lpParameter);
SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SOCKET_ERROR == sockClient)
{
printf ("socket create failed. ip=[%s] errno=[%d] ", szIp, WSAGetLastError());
return -2;
}
BOOL bBroadcast = TRUE;                             
if (0 != setsockopt ( sockClient,SOL_SOCKET,SO_BROADCAST, (CHAR *)&bBroadcast, sizeof(BOOL)))
{
printf ("setsockopt failed. ip=[%s] errno=[%d]", szIp, WSAGetLastError());
return -3;
}
SOCKADDR_IN addrClient = {0};
addrClient.sin_family = AF_INET;
addrClient.sin_addr.s_addr = inet_addr(szIp);
addrClient.sin_port = 0; /// 0 表示由系统自动分配端口号
if (0 != bind (sockClient, (sockaddr*)&addrClient, sizeof(addrClient)))
{
printf ("bind failed.ip=[%s] errno=[%d]\n", szIp, WSAGetLastError());
}
SOCKADDR_IN addrServer = {0};                              
addrServer.sin_family = AF_INET;
addrServer.sin_addr.s_addr = htonl ( INADDR_BROADCAST );
addrServer.sin_port = htons (10001);          
int nConunter = 0;     
while(1) 
{
char pcSendMsg[UCHAR_MAX] = {0};
time_t rawTime;
time(&rawTime);
tm *t = localtime(&rawTime);
sprintf(pcSendMsg, "%04d-%02d-%02d %02d-%02d-%02d | ip=[%s]", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, szIp);
sendto ( sockClient, pcSendMsg, strlen(pcSendMsg)+1, 0, (SOCKADDR *) &addrServer, sizeof ( SOCKADDR_IN ));
printf("%s\n",pcSendMsg);
Sleep(1000);
}
closesocket(sockClient);  
return 0;
}
int main()
{
WSADATA wsaData = {0};                                   
if(0 != WSAStartup(MAKEWORD( 2, 2 ), &wsaData ))     
{
printf("WSAStartup failed.errno=[%d]", WSAGetLastError());//初始化失败返回-1
return -1;
}
char hostname[1024] = {0};
gethostname(hostname, sizeof(hostname));    //获得本地主机名
PHOSTENT hostinfo = gethostbyname(hostname);//信息结构体
while(*(hostinfo->h_addr_list) != NULL)        //输出IP地址
{
char* ip = inet_ntoa(*(struct in_addr *) *hostinfo->h_addr_list);
CreateThread(NULL, 0, ThreadProc, ip, 0, 0);
Sleep(100);
hostinfo->h_addr_list++;
}
Sleep(INFINITE);
 
WSACleanup();
return 0;
}

一、main函数中,打开网络模块:

WSADATA wsaData = {0};                                   

if(0 != WSAStartup(MAKEWORD( 2, 2 ), &wsaData ))     

{

printf("WSAStartup failed.errno=[%d]", WSAGetLastError());//初始化失败返回-1

return -1;

}

获取本地主机名称:

char hostname[1024] = {0};

gethostname(hostname, sizeof(hostname));    //获得本地主机名

通过主机名称,遍历计算机上的所有的网卡,并将网卡的ip创建线程回调函数

PHOSTENT hostinfo = gethostbyname(hostname);//信息结构体

while(*(hostinfo->h_addr_list) != NULL)        //输出IP地址

{

char* ip = inet_ntoa(*(struct in_addr *) *hostinfo->h_addr_list);

CreateThread(NULL, 0, ThreadProc, ip, 0, 0);

Sleep(100);

hostinfo->h_addr_list++;

}

二、ThreadProc 线程回调函数

记录一个网卡对应的ip地址

char szIp[16] = {0};

strcpy (szIp, (char*)lpParameter);

创建一个udp socket:

SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

if (SOCKET_ERROR == sockClient)

{

printf ("socket create failed. ip=[%s] errno=[%d] ", szIp, WSAGetLastError());

return -2;

}

将socket 同网卡(ip)绑定,端口给0,交由系统随机分配:

SOCKADDR_IN addrClient = {0};

addrClient.sin_family = AF_INET;

addrClient.sin_addr.s_addr = inet_addr(szIp);

addrClient.sin_port = 0; /// 0 表示由系统自动分配端口号

if (0 != bind (sockClient, (sockaddr*)&addrClient, sizeof(addrClient)))

{

printf ("bind failed.ip=[%s] errno=[%d]\n", szIp, WSAGetLastError());

}

消息循环发送消息

while(1) 

{

char pcSendMsg[UCHAR_MAX] = {0};

time_t rawTime;

time(&rawTime);

tm *t = localtime(&rawTime);

sprintf(pcSendMsg, "%04d-%02d-%02d %02d-%02d-%02d | ip=[%s]", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, szIp);

sendto ( sockClient, pcSendMsg, strlen(pcSendMsg)+1, 0, (SOCKADDR *) &addrServer, sizeof ( SOCKADDR_IN ));

printf("%s\n",pcSendMsg);

Sleep(1000);

}

关闭socketclosesocket(sockClient);  


×
打赏作者
最新回复 (0)
查看全部
全部楼主
返回