gpt4 book ai didi

c - 使用单个套接字接收单播和多播数据

转载 作者:太空宇宙 更新时间:2023-11-04 04:23:34 25 4
gpt4 key购买 nike

我正在开发一个基于网络的应用程序,我想在其中接收单播和多播数据。所以我想知道是否可以使用单个套接字同时接收单播数据和多播数据。这是我的代码,截至目前我只能接收单播数据而不能接收多播数据。

void* rec(void* t)
{
printf("Rec Thread created\n");
char buf[200];
struct sockaddr_in soc;
soc.sin_family=AF_INET;
soc.sin_addr.s_addr=inet_addr("123.1.2.3");
soc.sin_port=htons(1234);

long sock_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

bind(sock_fd,(struct sockaddr *)&soc,sizeof(sockaddr_in));

struct ip_mreq mreq;
memset(&mreq,0,sizeof(struct ip_mreq));
mreq.imr_multiaddr.s_addr=inet_addr("235.5.5.5");
mreq.imr_interface.s_addr=inet_addr("123.1.2.3");

setsockopt(sock_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))

while(true)
{
memset(buf,0,sizeof(buf));
long size=recvfrom(sock_fd,buf,200,0,NULL,NULL);
if(size>0)
{
printf("recvd %s\n",buf);
}
else
{
perror("Error receving data");
}
}
}

int main(int argc,char* argv[])
{
pthread_create(&pt,NULL,rec,NULL);
sleep(2);
char buf[]="Hello World!;
struct sockaddr_in soc;
soc.sin_family=AF_INET;
soc.sin_addr.s_addr=inet_addr("123.1.2.3");
soc.sin_port=htons(1234);

long sock_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

sendto(sock_fd,buf,sizeof(buf),0,(struct sockaddr *)&soc,sizeof(sockaddr_in));

struct sockaddr_in msoc;
msoc.sin_family=AF_INET;
msoc.sin_addr.s_addr=inet_addr("235.5.5.5");
msoc.sin_port=htons(1234);

char mbuf[]="Hi All!";
sendto(sock_fd,mbuf,sizeof(mbuf),0,(struct sockaddr *)&msoc,sizeof(sockaddr_in));

return 0;
}

最佳答案

这是可能的。或者至少“有点”是可能的。

考虑以下代码:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main(void) {
struct sockaddr_in vSSocket;
vSSocket.sin_family = AF_INET;
vSSocket.sin_addr.s_addr = INADDR_ANY;
vSSocket.sin_port = htons(1234);

int vSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (vSocket < 0) {
perror("socket");
return 1;
}

struct ip_mreq vReq;
vReq.imr_multiaddr.s_addr = inet_addr("235.5.5.5");
vReq.imr_interface.s_addr = inet_addr("123.1.2.3");
if (setsockopt(vSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vReq, sizeof(vReq)) < 0) {
perror("setsockopt 2");
return 1;
}
if (bind(vSocket, (struct sockaddr *)&vSSocket, sizeof(vSSocket)) == -1) {
perror("bind");
return 1;
}
ssize_t r;
char vBuf[256];
while (1) {
r = recv(vSocket, vBuf, sizeof(vBuf), 0);
if (r < 0) {
perror("recv");
break;
}
if (memcmp(vBuf, "quit", 4) == 0) {
printf("quit\n");
break;
}
write(1, vBuf, r);
}
return 0;
}

诀窍是:将套接字绑定(bind)到 INADDR_ANY 地址。所以它会监听你机器上的每个接口(interface)。此外,地址为 123.1.2.3 的接口(interface)加入多播组 235.5.5.5,因此它将接收该地址的任何数据包。

您可以使用出色的 socat 工具测试此解决方案。发送到多播地址:

socat STDIO UDP4-DATAGRAM:235.5.5.5:1234

发送到单播地址:

socat STDIO UDP4-DATAGRAM:123.1.2.3:1234

程序应输出您发送给它的任何内容,并在收到以“quit”开头的数据包时退出。

关于c - 使用单个套接字接收单播和多播数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43897353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com