首页 > 解决方案 > 无法使用 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;

}

标签: cnetworkingudpmulticast

解决方案


您的服务器发送到错误的地址。

服务器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)

推荐阅读