Java Socket:Java-NIO-ServerSocketChannel(二)

2014-11-24 08:59:13 · 作者: · 浏览: 5
= ssc.socket();
ss.bind(new InetSocketAddress(8989));
// set no blocking
ssc.configureBlocking(false);
ssc.accept();
System.out.println(1);
}
运行这个程序 有1 输出!!
这就是因为 它是非阻塞模式的。
SocketChannel
[java]
public abstract class SocketChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
// This is a partial API listing
public static SocketChannel open() throws IOException;
public static SocketChannel open(InetSocketAddress remote) throws IOException;
public abstract Socket socket();
public abstract boolean connect(SocketAddress remote) throws IOException;
public abstract boolean isConnectionPending();
public abstract boolean finishConnect() throws IOException;
public abstract boolean isConnected();
public final int validOps();
}
Socket和SocketChannel类封装点对点、有序的网络连接,类似于我们所熟知并喜爱的TCP/IP网络连接。SocketChannel扮演客户端发起同一个监听服务器的连接。直到连接成功,它才能收到数据并且只会从连接到的地址接收
每个SocketChannel对象创建时都是同一个对等的java.net.Socket对象串联的。静态的open( )方法可以创建一个新的SocketChannel对象,而在新创建的SocketChannel上调用socket( )方法能返回它对等的Socket对象;在该Socket上调用getChannel( )方法则能返回最初的那个SocketChannel。
新创建的SocketChannel虽已打开却是未连接的。在一个未连接的SocketChannel对象上尝试一个I/O操作会导致NotYetConnectedException异常。
我们可以通过在通道上直接调用connect( )方法或在通道关联的Socket对象上调用connect( )来将该socket通道连接。
一旦一个socket通道被连接,它将保持连接状态直到被关闭。
您可以通过调用布尔型的isConnected( )方法来测试某个SocketChannel当前是否已连接。
[java]
第二种带InetSocketAddress参数形式的open( )是在返回之前进行连接的便捷方法。这段代码:
SocketChannel socketChannel = SocketChannel.open (new InetSocketAddress ("somehost", somePort));
等价于下面这段代码:
SocketChannel socketChannel = SocketChannel.open( );
socketChannel.connect (new InetSocketAddress ("somehost", somePort));
1 如果您选择使用传统方式进行连接——通过在对等Socket对象上调用connect( )方法,那么传统的连接语义将适用于此。线程在连接建立好或超时过期之前都将保持阻塞。
2 如果您选择通过在通道上直接调用connect( )方法来建立连接并且通道处于阻塞模式(默认模式),那么连接过程实际上是一样的。在SocketChannel上并没有一种connect( )方法可以让您指定超时(timeout)值,当connect( )方法在非阻塞模式下被调用时SocketChannel提供并发连接:它发起对请求地址的连接并且立即返回值。
如果返回值是true,说明连接立即建立了(这可能是本地环回连接);
如果连接不能立即建立,connect( )方法会返回false且并发地继续连接建立过程。
面向流的的socket建立连接状态需要一定的时间,因为两个待连接系统之间必须进行包对话以建立维护流socket所需的状态信息。
跨越开放互联网连接到远程系统会特别耗时。假如某个SocketChannel上当前正由一个并发连接,isConnectPending( )方法就会返回true值。调用finishConnect( )方法来完成连接过程,该方法任何时候都可以安全地进行调用。假如在一个非阻塞模式的SocketChannel对象上调用finishConnect( )方法,将可能出现下列情形之一:
connect( )方法尚未被调用。那么将产生NoConnectionPendingException异常。
连接建立过程正在进行,尚未完成。那么什么都不会发生,finishConnect( )方法会立即返回false值。
在非阻塞模式下调用connect( )方法之后,SocketChannel又被切换回了阻塞模式。那么如果有必要的话,调用线程会阻塞直到连接建立完成,finishConnect( )方法接着就会返回true值。
在初次调用connect( )或最后一次调用finishConnect( )之后,连接建立过程已经完成。那么SocketChannel对象的内部状态将被更新到已连接状态,finishConnect( )方法会返回true值,然后SocketChannel对象就可以被用来传输数据了。
连接已经建立。那么什么都不会发生,finishConnect( )方法会返回true值。
当通道处于中间的连接等待(connection-pending)状态时,您只可以调用finishConnect( )、isConnectPending( )或isConnected( )方法。
一旦连接建立过程成功完成,isConnected( )将返回true值。
[java]
InetSocketAddress addr = new InetSocketAddress (host, port);
SocketChannel sc =