2013-05-03 27 views
1

我们有一个谈话到另一台主机通过套接字类,它看起来是这样的:除非主机关闭,然后一个SocketChannel超时上与插座使用NIO的SocketChannel

SocketChannel sc = SocketChannel.open(new InetSocketAddress(HOST, PORT)); 
sc.configureBlocking(true); 

... 
sc.write(...) 
sc.read(...) 

这个类的伟大工程。永远打开块。我试着这样做,使这个超时如下:

SocketChannel = SocketChannel.open(); 
sc.configureBlocking(false); 
boolean result = socketChannel.connect(new InetSocketAddress(HOST, PORT)); 
if (!result) { 
    long startTime = System.currentTimeMillis(); 
    while (!socketChannel.finishConnect()) { 
     if (System.currentTimeMillis() - startTime< 1000) { 
      // keep trying 
      Thread.sleep(100); 
     } else { 
      // FAILED! 
      enabled = false; 
      return; 
     } 
    } 
} 
// SUCCESS! 
socketChannel.configureBlocking(true); 
enabled = true 

那么出于某种原因finishConnect()永远阻塞的时候我会想到是不是在所有的块。有任何想法吗?

+0

阻塞是NIO的默认行为,因此即使大多数人认为它是关于非阻塞IO,您也不需要将其设置为BTW。 AFAIK你不能改变阻塞模式。 – 2013-05-04 05:27:36

+2

@PeterLawrey当然可以。这就是'configureBlocking()'的用途。 – EJP 2013-05-04 10:00:23

+0

@EJP感谢您的纠正。我没有看到它在一个区块中使用,并在以后切换到另一个区块。 – 2013-05-04 11:25:13

回答

4

你做错了。

  1. 创建未连接的SocketChannel并在阻塞模式下进行定时连接。

OR

  • 使用Selector在非阻塞模式。注册频道OP_CONNECT并选择。当它变得可以连接时,请致电finishConnect(),,如果它返回true注销OP_CONNECT并继续I/O。如果它返回false,请继续选择。如果它抛出异常,放弃连接,则失败。使用选择超时。不是一个旋转循环。
  • +0

    顺便说一句你可以安全地改变阻塞模式吗? – 2013-05-04 05:27:59

    +0

    谢谢。有人可以解释什么“定时连接阻塞模式意味着”你的意思是做一个阻塞连接在另一个线程,并在该线程完成或不完成? – dgrant 2013-05-06 19:08:34

    +2

    否。阻塞模式下的定时连接通过['Socket.connect(endpoint,timeout)'](http://docs.oracle.com/javase/7/docs/api/java/net/Socket)完成。 html#connect(java.net.SocketAddress,%20int))方法。 – EJP 2013-05-07 05:32:14