With Merlin build 63, when the {Server}SocketChannel APIs are used to produce java.net.Socket objects, the resulting objects return bogus values for remote port, local address, and sometimes local port. This bug can make Socket objects with associated channels impossible to pass to code that expects typical java.net.Socket behavior.
The program below "ChannelSocketTest" creates a ServerSocket bound to listen on a TCP port and a Socket connected to that port, and then it accepts the connection, resulting in the server-side peer Socket object.
If the first command-line argument is "true", then the initial ServerSocket and client Socket are created using the NIO channel APIs; that is, first a {Server}SocketChannel is created with the appropriate open() method, and then the corresponding {Server}Socket object is retrieved with the appropriate socket() method.
Otherwise, the java.net.{Server}Socket constructors are used.
Finally, the program prints out the result of calling the get*Address() and get*Port() methods on all three java.net.{Server}Socket objects. My understanding is that this final output should be identical regardless of whether or not the {Server}Socket objects were created from {Server}SocketChannels, but when run against Merlin build 63, it differs as shown below:
[terrier] 43 % java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b63)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b63, mixed mode)
[terrier] 44 % java ChannelSocketTest false
opened ServerSocket: ServerSocket[unbound]
bound ServerSocket: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=2019]
opened Socket: Socket[unconnected]
connected Socket: Socket[addr=/127.0.0.1,port=2019,localport=53026]
accepted Socket: Socket[addr=/127.0.0.1,port=53026,localport=2019]
========================================
*** ServerSocket info:
getInetAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 2019
*** client Socket info:
getInetAddress(): /127.0.0.1
getPort(): 2019
getLocalAddress(): /127.0.0.1
getLocalPort(): 53026
*** accepted Socket info:
getInetAddress(): /127.0.0.1
getPort(): 53026
getLocalAddress(): /127.0.0.1
getLocalPort(): 2019
[terrier] 45 % java ChannelSocketTest true
opened ServerSocketChannel: sun.nio.ch.ServerSocketChannelImpl@4f2c80
associated ServerSocket: ServerSocket[unbound]
bound ServerSocket: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=2019]
opened SocketChannel: sun.nio.ch.SocketChannelImpl@42719c
associated Socket: ChannelSocket[unconnected]
connected Socket: ChannelSocket[remote=/127.0.0.1 : 2019,local=/127.0.0.1 : 53031]
accepted Socket: ChannelSocket[remote=/127.0.0.1 : 53031,local=null]
========================================
*** ServerSocket info:
getInetAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 2019
*** client Socket info:
getInetAddress(): /127.0.0.1
getPort(): 0
getLocalAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 53031
*** accepted Socket info:
getInetAddress(): /127.0.0.1
getPort(): 0
getLocalAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 0
Note that in the (latter) case when the {Server}Socket objects were obtained from {Server}SocketChannel objects, for the client Socket, the remote port and the client address have incorrect values, and fpr the accepted Socket, the remote port, local address, and local port have incorrect values.
Also note that looking at the toString() output above, it appears that the client Socket does reflect the proper local and remote address and port in that form, and the accepted Socket has the correct remote port, but it still lacks the local address and port in that form.
In both cases, a "netstat -an" reports socket status like this (modulo the randomly assigned client port binding):
*.2019 *.* 0 0 24576 0 LISTEN
127.0.0.1.53031 127.0.0.1.2019 32768 0 32768 0 ESTABLISHED
127.0.0.1.2019 127.0.0.1.53031 32768 0 32768 0 ESTABLISHED
Here is the code for ChannelSocketTest used to produce the above output:
import java.io.*;
import java.net.*;
import java.nio.*;
public class ChannelSocketTest {
private static final int PORT = 2019;
public static void main(String[] args) throws Exception {
PrintStream p = System.err;
boolean useChannels = Boolean.valueOf(args[0]).booleanValue();
int port = (args.length > 1 ? Integer.parseInt(args[1]) : PORT);
// open server socket
ServerSocket serverSocket;
if (useChannels) {
ServerSocketChannel serverSocketChannel =
ServerSocketChannel.open();
p.println("opened ServerSocketChannel: " +
serverSocketChannel);
serverSocket = serverSocketChannel.socket();
p.println("associated ServerSocket: " + serverSocket);
} else {
serverSocket = new ServerSocket();
p.println("opened ServerSocket: " + serverSocket);
}
// bind server socket to port
SocketAddress bindAddr = new InetSocketAddress(port);
serverSocket.bind(bindAddr);
p.println("bound ServerSocket: " + serverSocket);
p.println();
// open client socket
Socket socket;
if (useChannels) {
SocketChannel socketChannel = SocketChannel.open();
p.println("opened SocketChannel: " + socketChannel);
socket = socketChannel.socket();
p.println("associated Socket: " + socket);
} else {
socket = new Socket();
p.println("opened Socket: " + socket);
}
// connect client socket to port
SocketAddress connectAddr =
new InetSocketAddress("127.0.0.1", serverSocket.getLocalPort());
socket.connect(connectAddr);
p.println("connected Socket: " + socket);
p.println();
// accept connection
Socket acceptedSocket = serverSocket.accept();
p.println("accepted Socket: " + acceptedSocket);
p.println();
p.println("========================================");
p.println("*** ServerSocket info: ");
dumpServerSocketInfo(serverSocket, p);
p.println();
p.println("*** client Socket info: ");
dumpSocketInfo(socket, p);
p.println();
p.println("*** accepted Socket info: ");
dumpSocketInfo(acceptedSocket, p);
p.println();
Thread.sleep(5000);
}
private static void dumpServerSocketInfo(ServerSocket s, PrintStream p) {
p.println("getInetAddress(): " + s.getInetAddress());
p.println("getLocalPort(): " + s.getLocalPort());
}
private static void dumpSocketInfo(Socket s, PrintStream p) {
p.println("getInetAddress(): " + s.getInetAddress());
p.println("getPort(): " + s.getPort());
p.println("getLocalAddress(): " + s.getLocalAddress());
p.println("getLocalPort(): " + s.getLocalPort());
}
}
The program below "ChannelSocketTest" creates a ServerSocket bound to listen on a TCP port and a Socket connected to that port, and then it accepts the connection, resulting in the server-side peer Socket object.
If the first command-line argument is "true", then the initial ServerSocket and client Socket are created using the NIO channel APIs; that is, first a {Server}SocketChannel is created with the appropriate open() method, and then the corresponding {Server}Socket object is retrieved with the appropriate socket() method.
Otherwise, the java.net.{Server}Socket constructors are used.
Finally, the program prints out the result of calling the get*Address() and get*Port() methods on all three java.net.{Server}Socket objects. My understanding is that this final output should be identical regardless of whether or not the {Server}Socket objects were created from {Server}SocketChannels, but when run against Merlin build 63, it differs as shown below:
[terrier] 43 % java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b63)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b63, mixed mode)
[terrier] 44 % java ChannelSocketTest false
opened ServerSocket: ServerSocket[unbound]
bound ServerSocket: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=2019]
opened Socket: Socket[unconnected]
connected Socket: Socket[addr=/127.0.0.1,port=2019,localport=53026]
accepted Socket: Socket[addr=/127.0.0.1,port=53026,localport=2019]
========================================
*** ServerSocket info:
getInetAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 2019
*** client Socket info:
getInetAddress(): /127.0.0.1
getPort(): 2019
getLocalAddress(): /127.0.0.1
getLocalPort(): 53026
*** accepted Socket info:
getInetAddress(): /127.0.0.1
getPort(): 53026
getLocalAddress(): /127.0.0.1
getLocalPort(): 2019
[terrier] 45 % java ChannelSocketTest true
opened ServerSocketChannel: sun.nio.ch.ServerSocketChannelImpl@4f2c80
associated ServerSocket: ServerSocket[unbound]
bound ServerSocket: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=2019]
opened SocketChannel: sun.nio.ch.SocketChannelImpl@42719c
associated Socket: ChannelSocket[unconnected]
connected Socket: ChannelSocket[remote=/127.0.0.1 : 2019,local=/127.0.0.1 : 53031]
accepted Socket: ChannelSocket[remote=/127.0.0.1 : 53031,local=null]
========================================
*** ServerSocket info:
getInetAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 2019
*** client Socket info:
getInetAddress(): /127.0.0.1
getPort(): 0
getLocalAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 53031
*** accepted Socket info:
getInetAddress(): /127.0.0.1
getPort(): 0
getLocalAddress(): 0.0.0.0/0.0.0.0
getLocalPort(): 0
Note that in the (latter) case when the {Server}Socket objects were obtained from {Server}SocketChannel objects, for the client Socket, the remote port and the client address have incorrect values, and fpr the accepted Socket, the remote port, local address, and local port have incorrect values.
Also note that looking at the toString() output above, it appears that the client Socket does reflect the proper local and remote address and port in that form, and the accepted Socket has the correct remote port, but it still lacks the local address and port in that form.
In both cases, a "netstat -an" reports socket status like this (modulo the randomly assigned client port binding):
*.2019 *.* 0 0 24576 0 LISTEN
127.0.0.1.53031 127.0.0.1.2019 32768 0 32768 0 ESTABLISHED
127.0.0.1.2019 127.0.0.1.53031 32768 0 32768 0 ESTABLISHED
Here is the code for ChannelSocketTest used to produce the above output:
import java.io.*;
import java.net.*;
import java.nio.*;
public class ChannelSocketTest {
private static final int PORT = 2019;
public static void main(String[] args) throws Exception {
PrintStream p = System.err;
boolean useChannels = Boolean.valueOf(args[0]).booleanValue();
int port = (args.length > 1 ? Integer.parseInt(args[1]) : PORT);
// open server socket
ServerSocket serverSocket;
if (useChannels) {
ServerSocketChannel serverSocketChannel =
ServerSocketChannel.open();
p.println("opened ServerSocketChannel: " +
serverSocketChannel);
serverSocket = serverSocketChannel.socket();
p.println("associated ServerSocket: " + serverSocket);
} else {
serverSocket = new ServerSocket();
p.println("opened ServerSocket: " + serverSocket);
}
// bind server socket to port
SocketAddress bindAddr = new InetSocketAddress(port);
serverSocket.bind(bindAddr);
p.println("bound ServerSocket: " + serverSocket);
p.println();
// open client socket
Socket socket;
if (useChannels) {
SocketChannel socketChannel = SocketChannel.open();
p.println("opened SocketChannel: " + socketChannel);
socket = socketChannel.socket();
p.println("associated Socket: " + socket);
} else {
socket = new Socket();
p.println("opened Socket: " + socket);
}
// connect client socket to port
SocketAddress connectAddr =
new InetSocketAddress("127.0.0.1", serverSocket.getLocalPort());
socket.connect(connectAddr);
p.println("connected Socket: " + socket);
p.println();
// accept connection
Socket acceptedSocket = serverSocket.accept();
p.println("accepted Socket: " + acceptedSocket);
p.println();
p.println("========================================");
p.println("*** ServerSocket info: ");
dumpServerSocketInfo(serverSocket, p);
p.println();
p.println("*** client Socket info: ");
dumpSocketInfo(socket, p);
p.println();
p.println("*** accepted Socket info: ");
dumpSocketInfo(acceptedSocket, p);
p.println();
Thread.sleep(5000);
}
private static void dumpServerSocketInfo(ServerSocket s, PrintStream p) {
p.println("getInetAddress(): " + s.getInetAddress());
p.println("getLocalPort(): " + s.getLocalPort());
}
private static void dumpSocketInfo(Socket s, PrintStream p) {
p.println("getInetAddress(): " + s.getInetAddress());
p.println("getPort(): " + s.getPort());
p.println("getLocalAddress(): " + s.getLocalAddress());
p.println("getLocalPort(): " + s.getLocalPort());
}
}
- duplicates
-
JDK-4838137 problem of getLocalAddress().getHostAddress() in nio
-
- Closed
-