【问题标题】:Receiving UDP data in Java在 Java 中接收 UDP 数据
【发布时间】:2012-11-14 06:49:32
【问题描述】:

我正在尝试接收 PlayCap 向 Java 中的网络地址 192.168.103.255 端口 3000 广播的 UDP 数据,但我在设置时遇到了麻烦。这是我所拥有的:

DatagramSocket socket = new DatagramSocket();
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
socket.bind(address);

我从绑定调用中得到“java.net.SocketException: already bound”。我对网络非常缺乏经验,所以我可能在这里做错了什么。任何帮助表示赞赏。

这是堆栈跟踪:

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

【问题讨论】:

  • 一项服务(可能是您的程序的旧版本)已经在侦听端口 3000。或者终止该进程或找到一个新端口。

标签: java sockets networking udp


【解决方案1】:

我不想恢复旧线程,但我认为这个问题的答案不正确。当我使用类似的代码创建 DatagramSocket 时,我遇到了同样的问题。

DatagramSocket socket = new DatagramSocket();
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), 5566));

这会导致 SocketException

Exception in thread "main" java.net.SocketException: already bound
at java.net.DatagramSocket.bind(DatagramSocket.java:376)
at testapplication.TestApplication.main(TestApplication.java:25)

Java 结果:1

不是因为有另一个进程占用了同一个端口,而是我在使用默认构造函数时已经创建了一个 BOUND 数据报套接字。

new DatagramSocket()

根据javadoc

数据报套接字() 构造一个数据报套接字并将其绑定到任何可用端口 本地主机。

所以异常的原因是你试图绑定一个已经绑定的套接字。要使其工作,您需要使用以下构造函数创建一个 unbond 套接字

DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
socket.bind(address);

希望这会有所帮助...

【讨论】:

  • 非常有帮助 DatagramSocket socket = new DatagramSocket(null); 谢谢!
【解决方案2】:

执行
netstat -a -o -n
并从中您可以发现此端口已经绑定或未绑定(即使从这里您也可以获得所有绑定的端口).如果是,请尝试任何其他端口:)

【讨论】:

  • 我运行了该命令,但端口未列出(IP 地址 192.168.103.255 和端口 3000 均未列出)。另外,我无法使用其他端口,因为我试图在本地机器上接收从 PlayCap (signal11.us/oss/playcap) 广播的数据,而且我似乎无法指定要广播的端口。
  • 数据是否来自您的本地计算机?你试过 InetSocketAddress address = new InetSocketAddress("localhost", 3000);或 InetSocketAddress 地址 = new InetSocketAddress("127.0.0.1", 3000);
  • 192.168.103.255 不是我的 IP 地址。根据 WireShark,这是数据的目标地址。我需要做任何端口转发或禁用 Windows 防火墙吗?是的,我已经尝试过您的建议并得到相同的“已绑定”错误。
  • 好的,然后检查您的防火墙设置。您使用的是哪个操作系统?对于 somtime ,请关闭防火墙,然后检查 ..
  • 我正在使用 Windows 7,并且正在使用 Eclipse Juno 进行编程。我刚刚尝试关闭 WIndows 防火墙,但没有帮助。
【解决方案3】:

很可能您的应用程序运行了两次。或者您可能会执行两次相同的代码。即使是同一个应用,绑定两次也可能会失败。

对于初学者来说经常发生他们没有关闭之前的尝试(我也发生过),然后他们的端口已经在使用中。确保添加适当的异常处理,例如通过弹出消息“端口已在使用中”。

请注意,对于监听,您通常只绑定一个端口,没有明确的地址(您可能需要为此使用“0.0.0.0”)。然后你可以同时接收广播和单播。

我用来收听广播的代码很简单:

DatagramSocket s = new DatagramSocket();
s.bind(new InetSocketAddress(port))

请注意,我没有绑定到特定地址,而只是绑定到端口。

【讨论】:

  • 我刚刚尝试使用“0.0.0.0”并重新启动我的机器,两次都出现“已经绑定”错误。根据 WireShark,192.168.103.255 是数据的目的地址。向我提供数据的人表示,这个地址是数据广播的地方(这不是我的 IP 地址)。我会正确接收这些数据吗?
  • 无需重启。使用您的系统实用程序(例如netstat)查看哪个进程正在侦听端口。不同的端口可以工作吗?如果您对所有端口都收到相同的错误,这是一个策略问题(Windows 防火墙等),或者您的应用程序绑定了两次,第二次失败。
  • 我运行了 netstat,但地址和端口没有在任何地方列出。我尝试了不同的端口,但似乎无法绑定任何端口。我尝试的每个地址/端口都会给我同样的“已绑定”错误。我尝试关闭 Windows 防火墙,但没有帮助。我不认为我绑定了两次,因为我的应用程序实际上只是我在原始帖子中列出的代码(当然是在 try-catch 块内)。我还插入了您在帖子中列出的代码,但对于我尝试的任何端口仍然“已经绑定”!这太令人沮丧了!
  • 您使用哪个 java 版本?它可能是沙盒或类似的东西吗?你能用完整的堆栈跟踪更新问题吗?
  • 我的 Java 版本是“1.7.0_09-b05”。我怎么知道它是否是沙盒的?我添加了堆栈跟踪,但不幸的是我认为它不会很有帮助。
【解决方案4】:

检查端口 3000,它可能已被另一个应用程序使用。尝试使用不同的端口。

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多