c - 无法使用 UDP 进行双向多播连接
问题描述
必须使其服务器和客户端成为双向的,我应该能够在控制台中发送和接收数据。
我可以从服务器向客户端发送数据,但无法从客户端接收任何数据。卡在这很长时间不知道如何解决它。
我刚刚开始着手建立网络,这真的很有帮助。
这是我的代码。
服务器.c
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
struct in_addr localInterface;
struct sockaddr_in groupSock, rcv_addr;
int sd;
char databuf[1024];
int datalen = sizeof(databuf);
int main(int argc, char *argv[])
{
/* Create a datagram socket on which to send. */
socklen_t rcv_addr_size = sizeof(struct sockaddr_in);
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0)
{
perror("Opening datagram socket error");
exit(1);
}
else
printf("Opening the datagram socket...OK.\n");
memset((char*) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
groupSock.sin_addr.s_addr = inet_addr("226.1.1.1");
groupSock.sin_port = htons(4321);
localInterface.s_addr = inet_addr("127.0.0.1");
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char*) &localInterface,
sizeof(localInterface)) < 0) {
perror("Setting local interface error");
exit(1);
} else
printf("Setting the local interface...OK\n");
int read_size;
while (1) {
memset(databuf, 0x00, sizeof(databuf));
scanf("%s", databuf);
datalen = strlen(databuf) + 1;
if (sendto(sd, databuf, datalen, 0, (struct sockaddr*) &groupSock,
sizeof(groupSock)) < 0)
datalen = 1024;
memset(databuf, 0x00, sizeof(databuf));
read_size = recvfrom(sd, databuf, datalen, 0,
(struct sockaddr*) &rcv_addr, &rcv_addr_size);
printf("The message from multicast ckient is: \"%s\"\n", databuf);
}
return 0;
}
客户端.c
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
struct sockaddr_in localSock, rcv_addr;
struct ip_mreq group;
int sd;
int datalen;
char databuf[1024];
int main(int argc, char *argv[]) {
/* Create a datagram socket on which to receive. */
socklen_t rcv_addr_size = sizeof(struct sockaddr_in);
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0) {
perror("Opening datagram socket error");
exit(1);
}
else
printf("Opening datagram socket....OK.\n");
{
int reuse = 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse,
sizeof(reuse)) < 0) {
perror("Setting SO_REUSEADDR error");
close(sd);
exit(1);
} else
printf("Setting SO_REUSEADDR...OK.\n");
}
memset((char*) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(4321);
localSock.sin_addr.s_addr = INADDR_ANY;
if (bind(sd, (struct sockaddr*) &localSock, sizeof(localSock))) {
perror("Binding datagram socket error");
close(sd);
exit(1);
} else
printf("Binding datagram socket...OK.\n");
group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
group.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &group,
sizeof(group)) < 0) {
perror("Adding multicast group error");
close(sd);
exit(1);
} else
printf("Adding multicast group...OK.\n");
int read_size;
while (1) {
datalen = 1024;
memset(databuf, 0x00, sizeof(databuf));
read_size = recvfrom(sd, databuf, datalen, 0,
(struct sockaddr*) &rcv_addr, &rcv_addr_size);
printf("The message from multicast server is: \"%s\"\n", databuf);
memset(databuf, 0x00, sizeof(databuf));
scanf("%s", databuf);
datalen = strlen(databuf) + 1;
if (sendto(sd, databuf, datalen, 0, (struct sockaddr*) &localSock,
sizeof(localSock)) < 0)
break;
}
return 0;
}
解决方案
您的服务器发送到错误的地址。
服务器localSock
用作目标地址sendto
:
if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&localSock, sizeof(localSock)) < 0)
但是您将该地址设置为0:
localSock.sin_family = AF_INET;
localSock.sin_port = htons(4321);
localSock.sin_addr.s_addr = INADDR_ANY;
您想改用rcv_addr
,它被填充为来自 的源地址recvfrom
。使用这个地址作为目的地将把响应发回它来自的地方:
if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&rcv_addr, sizeof(rcv_addr)) < 0)
推荐阅读
- java - 在文件的每一行中查找有效模式
- laravel - 如何在不添加后缀.min.js的情况下缩小laravel mix中的JS?
- ruby-on-rails - Errno::EPIPE:http post multipart ruby 中的管道损坏
- javascript - 如何使用javascript仅从表单中提取所选信息并基于键和值创建字典?
- c - exec 导致程序的堆和栈等部分内存空间重新初始化
- postgresql - 使用 manage.py loaddata 加载数据时 Postgres 中的重复记录
- email - 为 sendmail 创建邮件列表
- html - 隐藏 Shopify Prestige 主题的未选择变体图像
- javascript - 从字符串 javascript 中删除元音,为什么我的解决方案不起作用?
- html - 是否可以在没有媒体查询的情况下为每个屏幕尺寸选择媒体?