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
", 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
", 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
", 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
", 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
", WSAGetLastError());
return 1;
}
return 0;
}
接收端代码:
到此这篇udp的广播和组播(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
", 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
", 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
", 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
", 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
", WSAGetLastError());
break;
}
else {
RecvBuf[NumBytes] = '0';
printf("Received multicast message from %s: %s
", 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;
}
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/57648.html