I have some code like this:
InetAddress bind = InetAddress.getByName("192.168.0.1")
MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,0));
socket.setInterface(bind);
On windows 7 and windows XP with JDK6u17,I go开发者_StackOverflow中文版t a SocketException: Socket operation on non socket.
But if I change the line 2 to :
MulticastSocket socket = new MulticastSocket(0);
It's ok, and works find too with jdk6u14.
Why? thanks.
EDIT: Why port 0 should be the matter?
MulticastSocket socket = new MulticastSocket(0);
Everything goes well with this code.But not
MulticastSocket socket = new MulticastSocket(new InetSocketAddress(bind,port));
Whatever the port is.
As you are binding to a specific interface, calling setInterface() to the same interface is redundant. Remove it. It's only needed when you bind to INADDR_ANY, or in Java an InetAddress of null (or unspecified as a parameter).
To address errors in some of the other answers, and their implications:
- Port zero is legal. It means a system-assigned port.
- You only need a MulticastSocket for receiving multicasts. For sending, you can just use a DatagramSocket.
- If the multicast interface needs to be specified, which it doesn't in this case, it can be done either via MulticastSocket.setInterface() or when calling joinGroup() or leaveGroup(). The latter option gives you granularity at the group level, but both techniques work. That's why they're both provided.
- If you don't bind to a specific interface you should definitely call setInterface(). If you are on a multi-homed host you must to call joinGroup()/leaveGroup() once per interface, if you want to receive via all of them.
And a question: is 192.168.0.1 an IP address of an NIC on the local machine? It needs to be.
According to the documentation, you are supposed to instantiate it with a port number (thus 0 would be valid).
I am not so sure. What's the constructor MulticastSocket(SocketAddress bindaddr) for. And why it works fine with jdk6u14,but not jdk6u17? And why it ok on windows 2003 server with jdk6u17?
On RHEL5.2 jdk1.4+
http://www.sockets.com/err_lst1.htm Berkeley description: An operation was attempted on something that is not a socket. The specified socket parameter refers to a file, not a socket.
WinSock description: Same as Berkeley. The socket input parameter is not a valid socket handle (either it never was valid, it's a file handle (not a socket handle), or if it was a socket handle, it has been closed).
Detailed description:
select(): fails with WSAENOTSOCK if any socket in an fd_set is an invalid socket handle.
Developer suggestions: Did you close a socket inadvertently in one part of an application without keeping another part notified? Use socket state in an application and/or handle this error gracefully as a non-fatal error.
when the MulticastSocket created,socket.isClosed()==true
I haven't used these classes before, but the Exception occurs on line 3 when you call the setInterface
method.
I would guess it's something to the effect that you're using the same reference twice or something. I found a snippet of code that looked like this, maybe this is how you should be doing it:
MulticastSocket ms = new MulticastSocket(new InetSocketAddress(0));
ms.setInterface(InetAddress.getByName("192.168.0.1"));
You should first create the Multicast socket with a well known port - something higher than 1024 and less than 65535 - as already stated 0 means the operating system will choose a port for you (but then its going to be kinda random - which I guess you don't want).
For multicast - you generally need to set the interface to use on joinGroup() not on creation - e.g:
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());
}
According to the MulticastSocket documentation you should use
Class D IP addresses in the range 224.0.0.0 to 239.255.255.255, inclusive
to bind a MulticastSocket. Apparently, the "192.168.0.1" is out of the multicast range.
精彩评论