绑定到特定的 IP 地址和端口以接收 UDP 数据 [英] Binding to a specific IP address and port to receive UDP data

查看:29
本文介绍了绑定到特定的 IP 地址和端口以接收 UDP 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试接收由 PlayCap 广播到网络地址 192.168.103.255 端口 3000 的 UDP 数据(http://www.signal11.us/oss/playcap/).我在绑定到此地址和端口时遇到问题.这是我的 Java 代码:

I am trying to receive UDP data that is broadcast to network address 192.168.103.255 port 3000 by PlayCap (http://www.signal11.us/oss/playcap/). I'm having problems binding to this address and port. Here's my Java code:

public static void main(String[] args) {
    try {
        DatagramSocket s = new DatagramSocket();
        InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
        s.bind(address);

        byte buffer[] = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        System.out.println("Waiting...");
        s.receive(packet);
        System.out.println("Received!");

    } catch (Exception e) {
        e.printStackTrace();
    }
}

这会返回错误:

java.net.SocketException: already bound
    at java.net.DatagramSocket.bind(Unknown Source)
    at runner.main(runner.java:12)

我已经运行了命令netstat -a -n",并且在输出的任何地方都没有列出地址 192.168.103.255 和端口 3000,所以我认为这个端口没有被使用.事实上,我尝试的任何地址/端口组合(包括我的静态 IP 地址)都会收到此错误.

I have run the command "netstat -a -n", and neither address 192.168.103.255 nor port 3000 are listed anywhere in the output, so I don't think this port is already in use. In fact, I get this error for any address/port combination I try (including my static IP address).

我还编写了一些 C 代码来创建一个套接字并绑定到该地址和端口,但它在绑定调用时也失败了.但是,此代码将绑定到我的静态 IP 地址 (192.168.1.149) 上的端口.这是代码:

I also wrote some C code to make a socket and bind to this address and port, but it also fails on the bind call. This code, however, will bind to ports on my static IP address (192.168.1.149). Here's that code:

#include <stdio.h>
#include <sys/types.h>
#include <winsock.h>
#include <unistd.h>

#define a1 192
#define a2 168
#define a3 103
#define a4 255
#define PORT 3000

int main() {

    /* Open windows connection */
    WSADATA w;
    if (WSAStartup(0x0101, &w) != 0)
    {
        printf("Could not open Windows connection.
");
        exit(0);
    }

    /* Clear out server struct */
    SOCKADDR_IN server;
    memset((void *)&server, '', sizeof(struct sockaddr_in));

    /* Set family and port */
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;
    server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;
    server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;
    server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;

    /* Open a datagram socket */
    int sd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sd == INVALID_SOCKET)
    {
        printf("Could not create socket.
");
        WSACleanup();
        exit(0);
    }

    /* Bind address to socket */
    if (bind(sd, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)) == -1)
    {
        printf("Could not bind name to socket.
");
        closesocket(sd);
        WSACleanup();
        exit(0);
    }

    /* Receive */
    char data[1024];
    printf("Waiting to receive...
");
    if (recv(sd, (char *)&data, (int)sizeof(data), 0))
    {
        printf("Error receiving data.
");
        closesocket(sd);
        WSACleanup();
        exit(0);
    }

    printf("Data: %s", data);

    return 0;
}

我使用的是 Windows 7 机器.我在 Eclipse 中运行 Java 代码.我正在使用以下命令使用 MinGW 编译 C 代码:

I'm using a Windows 7 machine. I'm running the Java code in Eclipse. I'm compiling the C code with MinGW using the command:

gcc a.c -lws2_32

(a.c"是文件名).

("a.c" is the file name).

虽然 Java 代码更重要,但我很高兴知道我的代码示例中哪里出了问题.非常感谢任何建议.

While the Java code is more important, I would be happy to know where I'm going wrong in either of my code examples. Any suggestions are very much appreciated.

推荐答案

改用你的 Java 代码试试这个:

Try this for your Java code instead:

public static void main(String[] args) {
    try {
        DatagramSocket s = new DatagramSocket(null);
        InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
        s.bind(address);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

为数据报套接字调用无参数构造函数将导致它绑定到一个随机的可用端口.一旦绑定,进一步尝试(重新)绑定将引发套接字异常(您看到的错误).要延迟"绑定,您可以在未绑定状态下创建数据报套接字(通过在构造函数中传递 null),然后稍后调用 bind.

Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind later on.

这篇关于绑定到特定的 IP 地址和端口以接收 UDP 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆