1

我有一些这样的代码:

InetAddress bind = InetAddress.getByName("192.168.0.1")
MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,0));
socket.setInterface(bind);

在带有 JDK6u17 的 windows 7 和 windows XP 上,我得到了 SocketException: Socket operation on non socket。

但是,如果我将第 2 行更改为:

MulticastSocket socket = new MulticastSocket(0);

没关系,使用 jdk6u14 也可以找到工作。

为什么?谢谢。

编辑: 为什么端口 0 应该是问题?

MulticastSocket socket = new MulticastSocket(0);

这段代码一切顺利。但不是

MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,port));

无论港口是什么。

4

6 回答 6

2

当您绑定到特定接口时,对同一接口调用 setInterface() 是多余的。去掉它。仅当您绑定到 INADDR_ANY 或在 Java 中为 null(或未指定为参数)的 InetAddress 时才需要它。

为了解决其他一些答案中的错误及其影响:

  1. 端口 0 是合法的。这意味着系统分配的端口。
  2. 您只需要一个 MulticastSocket 来接收多播。对于发送,您可以只使用 DatagramSocket。
  3. 如果需要指定多播接口,在这种情况下不需要指定,可以通过 MulticastSocket.setInterface() 或在调用 joinGroup() 或 leaveGroup() 时完成。后一个选项为您提供了组级别的粒度,但这两种技术都有效。这就是为什么它们都被提供的原因。
  4. 如果您不绑定到特定接口,则绝对应该调用 setInterface()。如果您在多宿主主机上,则必须在每个接口上调用一次 joinGroup()/leaveGroup(),如果您想通过所有接口接收。

还有一个问题:192.168.0.1是本地机器上网卡的IP地址吗?它需要。

于 2010-08-21T02:53:57.953 回答
0

根据文档,您应该使用端口号来实例化它(因此 0 将是有效的)。

于 2009-12-30T01:32:42.293 回答
0

我不太确定。MulticastSocket(SocketAddress bindaddr) 的构造函数是什么。为什么它适用于 jdk6u14,但不适用于 jdk6u17?为什么它可以在带有 jdk6u17 的 Windows 2003 服务器上运行?

在 RHEL5.2 jdk1.4+ 上

http://www.sockets.com/err_lst1.htm Berkeley 描述:试图对不是套接字的东西进行操作。指定的套接字参数是指文件,而不是套接字。

WinSock 描述:与伯克利相同。套接字输入参数不是一个有效的套接字句柄(或者它从来都不是有效的,它是一个文件句柄(不是一个套接字句柄),或者如果它是一个套接字句柄,它已经被关闭了)。

详细说明:

select():如果 fd_set 中的任何套接字是无效的套接字句柄,则使用 WSAENOTSOCK 失败。

开发人员建议:您是否在应用程序的某个部分无意中关闭了套接字,而没有通知另一部分?在应用程序中使用套接字状态和/或将此错误作为非致命错误优雅地处理。

当 MulticastSocket 创建时,socket.isClosed()==true

于 2009-12-30T02:08:08.947 回答
-1

根据MulticastSocket 文档,您应该使用

224.0.0.0 到 239.255.255.255 范围内的 D 类 IP 地址(含)

绑定 MulticastSocket。显然,“192.168.0.1”超出了多播范围。

于 2010-06-24T09:10:45.007 回答
-1

您应该首先使用众所周知的端口创建多播套接字 - 高于 1024 且小于 65535 - 如前所述 0 意味着操作系统将为您选择一个端口(但随后它会有点随机 - 我猜你不想)。

对于多播 - 您通常需要设置在 joinGroup() 上使用的接口而不是在创建时 - 例如:

MulticastSocket 套接字 = 新的 MulticastSocket(2121);

InetSocketAddress socketAddress = new InetSocketAddress("localhost", 2121);

if (networkInterfaceName != null){
        NetworkInterface ni = NetworkInterface.getByName(networkInterfaceName);
socket.joinGroup(this.socketAddress, ni);

}else {
   socket.joinGroup(socketAddress.getAddress());
}
于 2009-12-31T15:48:37.770 回答
-1

我之前没有使用过这些类,但是当您调用该setInterface方法时,异常发生在第 3 行。

我猜这大意是您两次使用相同的参考或其他东西。我发现了一段看起来像这样的代码,也许你应该这样做:

    MulticastSocket ms = new MulticastSocket(new InetSocketAddress(0));
    ms.setInterface(InetAddress.getByName("192.168.0.1"));
于 2009-12-30T02:33:20.267 回答