This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: Patch: fix non-blocking socket connect
On Tue, 2005-12-27 at 01:21 -0700, Tom Tromey wrote:
> In Azureus what happens is that we don't connect within the timeout
> period, so we throw an exception. However, the OS continues to try to
> connect, since we haven't told it to stop. Then later some other code
> sees that we've connected and gets confused since the socket's address
> is not set... hence this patch, which sets the address. But I think
> this patch is most likely incorrect.
Incorrect? Really?
> One final option is that I'm misinterpreting the Java API and that we
> really are supposed to set nonblocking mode and magically connect
> after Socket.connect has returned. This seems crazy, but I suppose it
> isn't completely impossible. A test is needed.
>From Stanley Brown's September '94 post. You need my Classpath
OP_CONNECT patch to make it work.
Note that it's SocketChannel.connect() that returns early, but it does
this by calling SocketImpl.connect() with a short timeout value (50),
catching the timeout exception, and then checking for the fd in
Selector.select() since we did the original connect in non-blocking
mode.
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;
public class TestConnect
{
public TestConnect()
{
try
{
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("gcc.gnu.org", 80));
channel.register(selector, SelectionKey.OP_CONNECT);
while (true)
{
selector.select();
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext())
{
SelectionKey selKey = (SelectionKey)it.next();
if (selKey.isConnectable())
{
System.out.println("Connection ready");
System.exit(0);
}
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
new TestConnect();
}
}