UDP 定向广播 (WinSock2) 失败

发布于 2025-01-12 05:48:41 字数 1756 浏览 3 评论 0原文

首先我要说的是,这是我在从事 PLC 和微控制器汇编编程 20 多年之后第一次涉足 C 语言世界。

我正在尝试将 UDP 数据报发送到网络广播地址,在本例中为 192.168.1.255。

我收到的错误是绑定失败,错误代码为 10049(来自 WSAGetLastError())。正如您从所附代码中看到的,我已经创建了套接字,填充了 sockaddr_in,并将 setockopt() 设置为 SO_BROADCAST。

对于我的一生,我无法弄清楚我做错了什么,我们将不胜感激地收到任何指示。

iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
    WSAErrorString("WSAStartup for TX failed");
    return(-1);
}
XPLMDebugString("UDP Server: WSAStartup TX complete.\n");

if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
    WSAErrorString("UDP Server: Could not create BECN socket");
    return(-1);
}

// setup the sockaddr_in structure
//
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
si_beacon.sin_port = htons(_UDP_TX_PORT);

// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
    WSAErrorString("Error in setting Broadcast option");
    closesocket(BeaconSocket);
    return(-1);
}

// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr *)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
    char buf[256];
    WSAErrorString("Bind to socket for UDP beacon failed");
    sprintf(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
    XPLMDebugString(buf);
    return(-1);
}

// start the UDP beacon
//
udp_becn_thread_id = CreateThread(NULL, 0, BeaconThread, NULL, 0, NULL);
if (!udp_becn_thread_id) {
    WSAErrorString("UDP Server: Error starting UDP Beacon");
    return (-1);
}

XPLMDebugString("UDP Server: bind complete. beacon ACTIVE.\n");


return(0);

Let me start by saying this is my first foray into the world of C after 20+ years of assembly programming for PLCs and MicroControllers.

I'm trying to send a UDP datagram to the network broadcast address, in this particular case, 192.168.1.255.

The error I'm getting is a bind failure with error code 10049 (from WSAGetLastError()). As you can see from the attached code, I've created the socket, populated sockaddr_in, and setsockopt() to SO_BROADCAST.

For the life of me I can't figure out what I'm doing wrong and any pointers would be gratefully received.

iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
    WSAErrorString("WSAStartup for TX failed");
    return(-1);
}
XPLMDebugString("UDP Server: WSAStartup TX complete.\n");

if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
    WSAErrorString("UDP Server: Could not create BECN socket");
    return(-1);
}

// setup the sockaddr_in structure
//
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
si_beacon.sin_port = htons(_UDP_TX_PORT);

// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
    WSAErrorString("Error in setting Broadcast option");
    closesocket(BeaconSocket);
    return(-1);
}

// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr *)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
    char buf[256];
    WSAErrorString("Bind to socket for UDP beacon failed");
    sprintf(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
    XPLMDebugString(buf);
    return(-1);
}

// start the UDP beacon
//
udp_becn_thread_id = CreateThread(NULL, 0, BeaconThread, NULL, 0, NULL);
if (!udp_becn_thread_id) {
    WSAErrorString("UDP Server: Error starting UDP Beacon");
    return (-1);
}

XPLMDebugString("UDP Server: bind complete. beacon ACTIVE.\n");


return(0);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

も让我眼熟你 2025-01-19 05:48:41

问题在于IP 地址本身。

我将代码复制到我的计算机上(对其进行了一些更改以使其编译),然后出现错误:

UDP Server: WSAStartup TX complete.
Bind to socket for UDP beacon failed
Port 47977, address 192.168.1.255

然后我更改了该行:

si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");

To

si_beacon.sin_addr.s_addr = inet_addr("192.168.0.127");

当我再次运行它时,一切正常:

UDP Server: WSAStartup TX complete.
Done successfully

问题是“绑定”地址需要是计算机在本地网络上的地址。 不是远程客户端。

另一种选择是使用地址:

si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");

它同时绑定到计算机上的所有网络接口。

作为参考,这是我使用的代码版本:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <string.h>

#include <WinSock2.h>
#include <WS2tcpip.h> // For inet_pton

#pragma comment(lib, "ws2_32.lib")

int main()
{
    {
        WSADATA wsaTxData;
        memset(&wsaTxData, 0, sizeof(WSADATA));
        const int iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
        if (iResult != NO_ERROR)
        {
            printf("%s", "WSAStartup for TX failed.\n");
            return -1;
        }
        printf("%s", "UDP Server: WSAStartup TX complete.\n");
    }

    SOCKET BeaconSocket;
    memset(&BeaconSocket, 0, sizeof(SOCKET));

    if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
        printf("%s", "UDP Server: Could not create BECN socket\n");
        return -1;
    }

    // setup the sockaddr_in structure
    //
    sockaddr_in si_beacon;
    memset(&si_beacon, 0, sizeof(sockaddr_in));
    si_beacon.sin_family = AF_INET;
    si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
    const unsigned short port_num = 0xbb69;
    si_beacon.sin_port = htons(port_num);

    // setup to broadcast
    //
    char so_broadcast_enabled = '1';
    if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
        printf("%s", "Error in setting Broadcast option\n");
        closesocket(BeaconSocket);
        return(-1);
    }

    // bind our socket
    //
    if (bind(BeaconSocket, (struct sockaddr*)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
    {
        char buf[256];
        printf("%s", "Bind to socket for UDP beacon failed\n");
        sprintf_s(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
        printf("%s", buf);
        return(-1);
    }

    printf("%s", "Done successfully");

    return 0;
}

The issue is the IP address itself.

I copied the code to my computer (changed it a bit to get it to compile) and I got the error:

UDP Server: WSAStartup TX complete.
Bind to socket for UDP beacon failed
Port 47977, address 192.168.1.255

I then changed the line:

si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");

To

si_beacon.sin_addr.s_addr = inet_addr("192.168.0.127");

And when I ran it again, everything worked:

UDP Server: WSAStartup TX complete.
Done successfully

The issue is that the "bind" address needs to be your computers address on the local network. Not the remote client.

Another alternative is to use the address:

si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");

which binds to all network interfaces on the computer at once.

For reference, here's the version of the code that I used:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <string.h>

#include <WinSock2.h>
#include <WS2tcpip.h> // For inet_pton

#pragma comment(lib, "ws2_32.lib")

int main()
{
    {
        WSADATA wsaTxData;
        memset(&wsaTxData, 0, sizeof(WSADATA));
        const int iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
        if (iResult != NO_ERROR)
        {
            printf("%s", "WSAStartup for TX failed.\n");
            return -1;
        }
        printf("%s", "UDP Server: WSAStartup TX complete.\n");
    }

    SOCKET BeaconSocket;
    memset(&BeaconSocket, 0, sizeof(SOCKET));

    if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
        printf("%s", "UDP Server: Could not create BECN socket\n");
        return -1;
    }

    // setup the sockaddr_in structure
    //
    sockaddr_in si_beacon;
    memset(&si_beacon, 0, sizeof(sockaddr_in));
    si_beacon.sin_family = AF_INET;
    si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
    const unsigned short port_num = 0xbb69;
    si_beacon.sin_port = htons(port_num);

    // setup to broadcast
    //
    char so_broadcast_enabled = '1';
    if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
        printf("%s", "Error in setting Broadcast option\n");
        closesocket(BeaconSocket);
        return(-1);
    }

    // bind our socket
    //
    if (bind(BeaconSocket, (struct sockaddr*)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
    {
        char buf[256];
        printf("%s", "Bind to socket for UDP beacon failed\n");
        sprintf_s(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
        printf("%s", buf);
        return(-1);
    }

    printf("%s", "Done successfully");

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文