UDP组播的原理及VC++ 多线程实现发送,接收的程序代码
时间: 2023-06-04 18:08:02 浏览: 404
UDP组播是基于IP多播技术实现的。IP多播是一种将数据包从一个源地址同时传输到多个目的地址的技术。在IP多播中,源地址标识了数据包发送方的IP地址,目的地址标识了多播组的IP地址。多播组的IP地址通常是一个特殊的地址,即D类IP地址(224.0.0.0~239.255.255.255)。多播组的地址由网络管理员分配,用于标识一个多播组。
UDP多播的原理是,将数据包从一个源地址同时传输到多个目的地址。数据包在传输过程中不需要建立连接,因此发送速度快,但可靠性低。UDP多播可以通过指定多播地址来进行多播,多播地址是D类IP地址。
以下是VC多线程实现UDP组播的发送和接收程序代码:
发送端代码:
```
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
int retVal;
// Initialize Winsock
retVal = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retVal != 0) {
printf("WSAStartup failed: %d\n", retVal);
return 1;
}
// Create a socket for sending data
SOCKET SendSocket;
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
printf("socket failed: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Set the TTL value for the outgoing packets
int TTL = 2;
retVal = setsockopt(SendSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&TTL, sizeof(TTL));
if (retVal == SOCKET_ERROR) {
printf("setsockopt failed: %d\n", WSAGetLastError());
closesocket(SendSocket);
WSACleanup();
return 1;
}
// Set up the destination address for sending the multicast message
char* MulticastAddr = "239.255.1.1";
struct sockaddr_in DestAddr;
DestAddr.sin_family = AF_INET;
DestAddr.sin_addr.s_addr = inet_addr(MulticastAddr);
DestAddr.sin_port = htons(1234);
// Send the multicast message using multiple threads
const int NumThreads = 4;
HANDLE hThreads[NumThreads];
for (int i = 0; i < NumThreads; i++) {
hThreads[i] = CreateThread(NULL, 0, SendThreadFunc, (LPVOID)&SendSocket, 0, NULL);
if (hThreads[i] == NULL) {
printf("CreateThread failed: %d\n", GetLastError());
closesocket(SendSocket);
WSACleanup();
return 1;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(NumThreads, hThreads, TRUE, INFINITE);
// Close the socket and clean up Winsock
closesocket(SendSocket);
WSACleanup();
return 0;
}
DWORD WINAPI SendThreadFunc(LPVOID lpParam)
{
SOCKET* pSendSocket = (SOCKET*)lpParam;
// Send a multicast message
char* MulticastMsg = "Hello, world!";
const int MsgLen = strlen(MulticastMsg);
int retVal = sendto(*pSendSocket, MulticastMsg, MsgLen, 0, (struct sockaddr*)&DestAddr, sizeof(DestAddr));
if (retVal == SOCKET_ERROR) {
printf("sendto failed: %d\n", WSAGetLastError());
return 1;
}
return 0;
}
```
接收端代码:
```
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
int retVal;
// Initialize Winsock
retVal = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retVal != 0) {
printf("WSAStartup failed: %d\n", retVal);
return 1;
}
// Create a socket for receiving data
SOCKET RecvSocket;
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
printf("socket failed: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Bind the socket to the local address
struct sockaddr_in LocalAddr;
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
LocalAddr.sin_port = htons(1234);
retVal = bind(RecvSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
if (retVal == SOCKET_ERROR) {
printf("bind failed: %d\n", WSAGetLastError());
closesocket(RecvSocket);
WSACleanup();
return 1;
}
// Join the multicast group
char* MulticastAddr = "239.255.1.1";
struct ip_mreq Mreq;
Mreq.imr_multiaddr.s_addr = inet_addr(MulticastAddr);
Mreq.imr_interface.s_addr = htonl(INADDR_ANY);
retVal = setsockopt(RecvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&Mreq, sizeof(Mreq));
if (retVal == SOCKET_ERROR) {
printf("setsockopt failed: %d\n", WSAGetLastError());
closesocket(RecvSocket);
WSACleanup();
return 1;
}
// Receive multicast messages
while (true) {
char RecvBuf[1024];
struct sockaddr_in SenderAddr;
int SenderAddrLen = sizeof(SenderAddr);
int NumBytes = recvfrom(RecvSocket, RecvBuf, sizeof(RecvBuf), 0, (struct sockaddr*)&SenderAddr, &SenderAddrLen);
if (NumBytes == SOCKET_ERROR) {
printf("recvfrom failed: %d\n", WSAGetLastError());
break;
}
else {
RecvBuf[NumBytes] = '\0';
printf("Received multicast message from %s: %s\n", inet_ntoa(SenderAddr.sin_addr), RecvBuf);
}
}
// Leave the multicast group, close the socket, and clean up Winsock
setsockopt(RecvSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&Mreq, sizeof(Mreq));
closesocket(RecvSocket);
WSACleanup();
return 0;
}
```