MulticastSocket:非套接字上的套接字操作

时间:2009-12-30 01:25:54

标签: java multicast

我有一些像这样的代码:

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:非套接字上的套接字操作。

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

MulticastSocket socket = new MulticastSocket(0);

没关系,并且使用jdk6u14也可以找到它。

为什么呢?感谢。

修改 为什么端口0应该是这个问题?

MulticastSocket socket = new MulticastSocket(0);

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

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

无论端口是什么。

6 个答案:

答案 0 :(得分:2)

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

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

  1. 端口零是合法的。它表示系统分配的端口。
  2. 您只需要一个MulticastSocket来接收多播。对于发送,您只需使用DatagramSocket。
  3. 如果需要指定多播接口(在这种情况下不需要),可以通过MulticastSocket.setInterface()或调用joinGroup()或leaveGroup()来完成。后一个选项为您提供组级别的粒度,但这两种方法都有效。这就是为什么他们都被提供的原因。
  4. 如果你没有绑定到特定的接口,你一定要调用setInterface()。如果您在多宿主主机上,则每个接口必须调用一次joinGroup()/ leaveGroup(),如果您想通过所有接口进行接收。
  5. 还有一个问题:本地机器上的NIC的IP地址是192.168.0.1吗?它需要。

答案 1 :(得分:0)

根据documentation,您应该使用端口号对其进行实例化(因此0将有效)。

答案 2 :(得分:0)

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

在RHEL5.2上jdk1.4 +

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

WinSock描述:与Berkeley相同。套接字输入参数不是有效的套接字句柄(它永远不是有效的,它是文件句柄(不是套接字句柄),或者如果它是套接字句柄,它已被关闭)。

详细说明:

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

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

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

答案 3 :(得分:-1)

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

我猜这是因为你使用相同的引用两次或者什么。 我发现了一段看起来像这样的代码,也许你应该这样做:

    MulticastSocket ms = new MulticastSocket(new InetSocketAddress(0));
    ms.setInterface(InetAddress.getByName("192.168.0.1"));

答案 4 :(得分:-1)

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

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

MulticastSocket socket = new 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());
}

答案 5 :(得分:-1)

根据MulticastSocket documentation你应该使用

  

范围内的D类IP地址   224.0.0.0至239.255.255.255,包括

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