我正在尝试接收由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 <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.\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代码。我正在使用命令编译C代码:
gcc a.c -lws2_32
(“a.c”是文件名)。
虽然Java代码更重要,但我很高兴知道我的代码示例中出现了什么问题。任何建议都非常感谢。
答案 0 :(得分:13)
请尝试将此代码用于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构造函数将导致它绑定到随机可用端口。一旦绑定,进一步尝试(重新)绑定将抛出套接字异常(带有您看到的错误)。要“延迟”绑定,您可以在未绑定状态下创建数据报套接字(通过在构造函数中传递null),然后再调用bind
。
答案 1 :(得分:3)
您不绑定广播地址以接收广播数据包。只需绑定到端口和地址INADDR_ANY
(抱歉,不知道如何在Java中表达),您将获得广播地址上该端口的数据包。
答案 2 :(得分:0)
Data appears that数据报构造函数接受要绑定的端口号。希望有帮助...