【问题标题】:trying to broadcast through udp socket试图通过 udp 套接字广播
【发布时间】:2013-06-03 03:17:57
【问题描述】:

我的广播服务器遇到了问题。基本上,我希望它从我启动它的那一刻起就连续发送广播。由于某种原因,它在从某个地方接收到连接之前不会启动。我一定搞砸了什么,但我不知道是什么。

这是我的代码:

WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    SOCKET sock;
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    char broadcast = 'a';

    if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        perror("broadcast options");
        closesocket(sock);
        return 1;
    }
    struct sockaddr_in Recv_addr;
    struct sockaddr_in Sender_addr;
    int len = sizeof(struct sockaddr_in);
    char recvBuff[50];
    int recvBuffLen = 50;
    //char sendMsg[] = "broadcast message from salam rofl";

    Recv_addr.sin_family = AF_INET;
    Recv_addr.sin_port = htons(PORT);
    Recv_addr.sin_addr.s_addr = INADDR_ANY;

    if(bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
    {
        perror("bind");
        _getch;
        closesocket(sock);
        return 1;
    }

    //recvfrom(sock, recvBuff, recvBuffLen, 0, (sockaddr *)&Sender_addr, &len);
    //cout << "\nreceived message: " << recvBuff;

    while(1)
    {
        Sleep(3000);


        //_getch();

        getTime();
        if(sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
        {
            perror("borhot send: ");
            _getch();
            closesocket(sock);
            return 0;
        }
        else cout << "message sent successfully";
    }

    _getch;
    closesocket(sock);
    WSACleanup();
    return 0;

基本上,如果我从 recvfrom 中删除,它会给我一个发送错误(“无错误”),这让我很困惑。另外,如果我用客户端发送一些东西,它将开始广播,但如果我与另一个客户端连接,则只有第一个客户端正在接收广播。

提前谢谢你。 我怀疑这很重要,但我正在尝试广播当前时间。

【问题讨论】:

  • 只是一个问题;我意识到这是超级旧的。为什么broadcast = 'a'?为什么不broadcast = 1
  • 哈,好问题 - 我可能不知道更好。这是很久以前的事了,我真的不记得这些了。看到我刚开始研究套接字时提出的问题很有趣。
  • 哈哈我同意,我已经回去几次了。

标签: c++ sockets udp winsock broadcast


【解决方案1】:

你没有初始化Sender_Addr,所以你没有告诉sendto()实际广播到哪里。

试试这个:

WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
    perror("socket creation");
    _getch;
    return 1;
}

BOOL enabled = TRUE;
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&enabled, sizeof(BOOL)) < 0)
{
    perror("broadcast options");
    _getch;
    closesocket(sock);
    return 1;
}

struct sockaddr_in Sender_addr;
Sender_addr.sin_family = AF_INET;
Sender_addr.sin_port = htons(BROADCAST_PORT);
Sender_addr.sin_addr.s_addr = inet_addr("Broadcast IP Here");

struct sockaddr_in Recv_addr;
Recv_addr.sin_family = AF_INET;
Recv_addr.sin_port = htons(PORT);
Recv_addr.sin_addr.s_addr = INADDR_ANY;

if (bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
{
    perror("bind");
    _getch;
    closesocket(sock);
    return 1;
}

while(1)
{
    Sleep(3000);

    getTime();
    if (sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
    {
        perror("borhot send: ");
        _getch();
        closesocket(sock);
        return 0;
    }

    cout << "message sent successfully";
}

_getch;
closesocket(sock);

WSACleanup();
return 0;

【讨论】:

  • Sender_addr.sin_addr.s_addr = inet_addr("Broadcast IP Here"); 让我有点困惑。您将发件人地址设置为广播IP?这个地址是什么?假设我在 10.0.0.x 上,应该说 10.0.0.255 吗?
  • Sender_addr 是广播数据的destination 地址。我只是使用 OP 原始代码中的相同变量名。 Sender_addr 可以重命名为 Send_addrTarget_addrBroadcast_addr 或任何对您更有意义的名称。 sender's 地址是实际执行广播的适配器的 IP。由于套接字本地绑定到INADDR_ANY,因此无论哪个适配器都可以到达广播IP所属的网络。如果子网掩码为255.255.255.010.0.0.255 将是您的10.0.0.x 网络的广播IP。
  • 使用GetAdaptersInfo()GetAdaptersAddresses() 获取/计算网络适配器的实际广播IP。
  • 啊,我明白了。谢谢。
【解决方案2】:

看起来您的Sender_addr 从未被初始化,因此当您删除recvfrom 时会出现错误,而当recvfrom 就位时,它会填充第一个要连接的客户端的地址(但从未更新)。

如果您不知道要向其广播的客户端的地址,则需要设置一些握手,他们向您发送 ping,您使用 recvfrom 接收它,并将他们的地址存储在列表中或者其他的东西。然后,当您广播时,您需要将您的消息发送到列表中的每个客户地址。

【讨论】:

  • 或者只是用子网的广播IP初始化Sender_addr,这是OP首先应该做的,否则启用SO_BROADCAST是没有用的。
猜你喜欢
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
相关资源
最近更新 更多