📄 udp.c
字号:
}
/*发送完毕后关闭套接字、释放占用资源*/
closesocket(socketBro);
WSACleanup();
}
/*广播消息接收函数*/
void broadcastRec()
{
BOOL optval = TRUE;
int addrBroLen;
char buf[256];
DWORD i=0;
/*该地址用来绑定套接字*/
addrRec.sin_family=AF_INET;
addrRec.sin_addr.s_addr=0;
addrRec.sin_port=htons(bPort);
/*该地址用来接收网路上广播的消息*/
addrBro.sin_family=AF_INET;
addrBro.sin_addr.s_addr=bcastAddr;
addrBro.sin_port=htons(bPort);
addrBroLen=sizeof(addrBro);
//创建UDP套接字
socketRec=socket(AF_INET,SOCK_DGRAM,0);
/*如果创建失败*/
if(socketRec==INVALID_SOCKET)
{
printf("Create socket error:%d",WSAGetLastError());
WSACleanup();
return;
}
/*设置该套接字为可重用类型*/
if(setsockopt(socketRec,SOL_SOCKET,SO_REUSEADDR,(char FAR *)&optval,
sizeof(optval))==SOCKET_ERROR)
/*如果设置失败*/
{
printf("setsockopt failed:%d",WSAGetLastError());
closesocket(socketRec);
WSACleanup();
return;
}
/*绑定套接字和地址*/
if(bind(socketRec,(struct sockaddr *)&addrRec,
sizeof(struct sockaddr_in))==SOCKET_ERROR)
/*如果绑定失败*/
{
printf("bind failed with: %d\n", WSAGetLastError());
closesocket(socketRec);
WSACleanup();
return ;
}
/*从广播地址接收消息*/
while(i<bCount)
{
recvfrom(socketRec,buf,256,0,(struct sockaddr FAR *)&addrBro,(int FAR *)&addrBroLen);
/*延迟2秒钟*/
Sleep(2000);
/*输出接收到缓冲区的消息*/
printf("%s\n",buf);
/*情况缓冲区*/
ZeroMemory(buf,256);
i++;
}
/*接收完毕后关闭套接字、释放占用资源*/
closesocket(socketRec);
WSACleanup();
}
/*多播控制函数*/
void mulControl()
{
int optval;
/*创建UDP套接字,用于多播*/
if ((socketMul = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0,
WSA_FLAG_MULTIPOINT_C_LEAF
| WSA_FLAG_MULTIPOINT_D_LEAF
| WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("socket failed with: %d\n", WSAGetLastError());
WSACleanup();
return ;
}
/*设置本地接口地址*/
addrLocal.sin_family = AF_INET;
addrLocal.sin_port = htons(mPort);
addrLocal.sin_addr.s_addr = dwInterface;
/*将UDP套接字绑定到本地地址上*/
if (bind(socketMul, (struct sockaddr *)&addrLocal,
sizeof(addrLocal)) == SOCKET_ERROR)
/*如果绑定失败*/
{
printf("bind failed with: %d\n", WSAGetLastError());
closesocket(socketMul);
WSACleanup();
return ;
}
/*设置多播地址各个选项*/
addrMul.sin_family = AF_INET;
addrMul.sin_port = htons(mPort);
addrMul.sin_addr.s_addr = dwMulticastGroup;
/*重新设置TTL值*/
optval = 8;
/*设置多播数据的TTL(存在时间)值。默认情况下,TTL值是1*/
if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&optval, sizeof(int)) == SOCKET_ERROR)
/*如果设置失败*/
{
printf("setsockopt(IP_MULTICAST_TTL) failed: %d\n",WSAGetLastError());
closesocket(socketMul);
WSACleanup();
return ;
}
/*如果指定了返还选项*/
if (bLoopBack)
{
/*设置返还选项为假,禁止将发送的数据返还给本地接口*/
optval = 0;
if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_LOOP,
(char *)&optval, sizeof(optval)) == SOCKET_ERROR)
/*如果设置失败*/
{
printf("setsockopt(IP_MULTICAST_LOOP) failed: %d\n",
WSAGetLastError());
closesocket(socketMul);
WSACleanup();
return ;
}
}
/*加入多播组*/
if ((sockJoin = WSAJoinLeaf(socketMul, (SOCKADDR *)&addrMul,
sizeof(addrMul), NULL, NULL, NULL, NULL,
JL_BOTH)) == INVALID_SOCKET)
/*如果加入不成功*/
{
printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError());
closesocket(socketMul);
WSACleanup();
return ;
}
}
/*多播消息发送函数*/
void multicastSend()
{
TCHAR sendbuf[BUFSIZE];
DWORD i;
int ret;
mulControl();
/*发送mCount条消息*/
for(i = 0; i < mCount; i++)
{
/*将待发送的消息写入发送缓冲区*/
sprintf(sendbuf, "server 1: This is a test: %d", i);
ret=sendto(socketMul, (char *)sendbuf, strlen(sendbuf), 0,
(struct sockaddr *)&addrMul, sizeof(addrMul));
/*如果发送失败*/
if(ret==SOCKET_ERROR)
{
printf("sendto failed with: %d\n",WSAGetLastError());
closesocket(sockJoin);
closesocket(socketMul);
WSACleanup();
return ;
}
/*如果发送成功*/
else
printf("Send message %d\n",i);
Sleep(500);
}
/*关闭套接字、释放占用资源*/
closesocket(socketMul);
WSACleanup();
}
/*多播消息接收函数*/
void multicastRec()
{
DWORD i;
struct sockaddr_in from;
TCHAR recvbuf[BUFSIZE];
int ret;
int len = sizeof(struct sockaddr_in);
mulControl();
/*接收mCount条消息*/
for(i = 0; i < mCount; i++)
{
/*将接收的消息写入接收缓冲区*/
if ((ret = recvfrom(socketMul, recvbuf, BUFSIZE, 0,
(struct sockaddr *)&from, &len)) == SOCKET_ERROR)
/*如果接收不成功*/
{
printf("recvfrom failed with: %d\n",WSAGetLastError());
closesocket(sockJoin);
closesocket(socketMul);
WSACleanup();
return ;
}
/*接收成功,输出接收的消息*/
recvbuf[ret] = 0;
printf("RECV: '%s' from <%s>\n", recvbuf,inet_ntoa(from.sin_addr));
}
/*关闭套接字、释放占用资源*/
closesocket(socketMul);
WSACleanup();
}
/*主函数*/
int main(int argc, char **argv)
{
WSADATA wsd;
initial();
GetArgments(argc, argv);
/*初始化Winsock*/
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup() failed\n");
return -1;
}
/*如果是执行广播程序*/
if(broadFlag)
{
/*以发送者身份发送消息*/
if(broadSendFlag)
{
broadcastSend();
return 0;
}
/*以接收者身份接收消息*/
else
{
broadcastRec();
return 0;
}
}
/*如果是执行多播程序*/
if(multiFlag)
{
/*以发送者身份发送消息*/
if(multiSendFlag)
{
multicastSend();
return 0;
}
/*以接收者身份接收消息*/
else
{
multicastRec();
return 0;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -