views:

89

answers:

2

Hi

Usually you have a single bound tcp port and several connections on these. At least there are usually more connections as bound ports. My case is different: I want to bind a lot of ports and usually have no (or at least very few) connections.

So I want to use NIO to accept the incoming connections.

However, I need to pass the accepted connections to the existing jsch ssh library. That requires IO sockets instead of NIO sockets, it spawns one (or two) thread(s) per connection. But that's fine for me.

Now, I thought that the following lines would deliver the very same result:

Socket a = serverSocketChannel.accept().socket();
Socket b = serverSocketChannel.socket().accep();
    SocketChannel channel = serverSocketChannel.accpet();
    channel.configureBlocking( true );
Socket c = channel.socket();
Socket d = serverSocket.accept();

However the getInputStream() and getOutputStream() functions of the returned sockets seem to work different. Only if the socket was accepted using the last call, jsch can work with it. In the first three cases, it fails (and I am sorry: I don't know why).

So is there a way to convert such a socket?

Regards, Steffen

A: 

This sequence works in our production environment:

final SocketAddress serverAddr =
    new InetSocketAddress(
        bind_address,
        server_port
    );

final ServerSocketChannel serverChannel = ServerSocketChannel.open( );

serverChannel.socket( ).bind(
    serverAddr,
    backlog
);

final SocketChannel socketChannel = serverChannel.accept( );

final Socket socket = socketChannel.socket( );

final OutputStream out = socket.getOutputStream( );

final InputStream in = socket.getInputStream( );

All channels will be in blocking mode by default.

Beware, that I did not show any cleanup/exception handling code.

Also, there are some bugs related to NIO and socket streams

Alexander Pogrebnyak
Thanks for the answer, but just this does NOT work for me (see second answer). Moreover that bug was in 5.0-beta, which should not be used anymore anyway...
Steffen Heil
@Steffen: this bug is alive and well in Java 6.
Alexander Pogrebnyak
A: 

The input and output streams returned by sockets obtained from SocketChannels are internally synchronized on the channel at some points. So you can't use them for full-duplex protocols like SSH, because the system will lock up. Same applies to streams converted from channels via the Channels class (which is what the first case amounts to).

EJP
This seems to explain, what I am experiencing. Is there any way to "decouple" them? Note that I do not use the accepted channel or socket anyhow anymore after getting its streams...
Steffen Heil
It's deeply internal.
EJP