绑定到特定的IP地址和端口以接收UDP数据

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

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地址)都会出现此错误。

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

 #include  #include  #include  #include  #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.\n"); exit(0); } /* Clear out server struct */ SOCKADDR_IN server; memset((void *)&server, '\0', 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.\n"); WSACleanup(); exit(0); } /* Bind address to socket */ if (bind(sd, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)) == -1) { printf("Could not bind name to socket.\n"); closesocket(sd); WSACleanup(); exit(0); } /* Receive */ char data[1024]; printf("Waiting to receive...\n"); if (recv(sd, (char *)&data, (int)sizeof(data), 0)) { printf("Error receiving data.\n"); closesocket(sd); WSACleanup(); exit(0); } printf("Data: %s", data); return 0; } 

我正在使用Windows 7机器。 我在Eclipse中运行Java代码。 我正在使用命令使用MinGW编译C代码:

 gcc ac -lws2_32 

(“ac”是文件名)。

虽然Java代码更重要,但我很高兴知道在我的任何一个代码示例中我出错了。 任何建议都非常感谢。

请尝试使用此代码来代替Java代码:

 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(); } } 

为数据报套接字调用no-arg构造函数将使其绑定到随机可用端口。 一旦绑定,进一步尝试(重新)绑定将抛出一个套接字exception(你看到的错误)。 要“延迟”绑定,您需要在未绑定状态下创建数据报套接字(通过在构造函数中传递null),然后再调用bind

您不绑定到广播地址以接收广播数据包。 只需绑定到端口和地址INADDR_ANY (对不起,不知道如何在Java中表达),您将在广播地址上获得该端口的数据包。

似乎 Datagram构造函数接受要绑定的端口号。 希望有帮助……