JAVA-NIO之Socket/ServerSocket Channel(详解)
一、ServerSocketChannel
JavaNIO中的ServerSocketChannel是一个可以监听新进来的TCP连接的通道,就像标准IO中的ServerSocket一样。ServerSocketChannel类在java.nio.channels包中。
打开ServerSocketChannel
通过调用ServerSocketChannel.open()方法来打开ServerSocketChannel.
关闭ServerSocketChannel
通过调用ServerSocketChannel.close()方法来关闭ServerSocketChannel.
监听新进来的连接
通过ServerSocketChannel.accept()方法监听新进来的连接。当accept()方法返回的时候,它返回一个包含新进来的连接的SocketChannel。因此,accept()方法会一直阻塞到有新连接到达。
通常不会仅仅只监听一个连接,在while循环中调用accept()方法.
当然,也可以在while循环中使用除了true以外的其它退出准则。
非阻塞模式
ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept()方法会立刻返回,如果还没有新进来的连接,返回的将是null。因此,需要检查返回的SocketChannel是否是null.如:
/** *socketserverchannel */ @Test publicvoidtext2()throwsIOException{ ServerSocketChannelchannel=ServerSocketChannel.open();//新建channel channel.socket().bind(newInetSocketAddress(9999));//监听端口 channel.configureBlocking(true);//设置阻塞 while(true){ SocketChannelaccept=channel.accept();//设置为阻塞,则此方法阻塞,直到有连接 //如果设置为非阻塞,需要在这里判断accept==null? ByteBufferbyteBuffer=ByteBuffer.allocate(1024); accept.read(byteBuffer); byteBuffer.flip();//反转 while(byteBuffer.hasRemaining()){//判断 System.err.println((char)byteBuffer.get());//输出 } } }
二、SocketChannel
JavaNIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:
打开一个SocketChannel并连接到互联网上的某台服务器。
一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
打开SocketChannel
下面是SocketChannel的打开方式:
关闭SocketChannel
当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:
从SocketChannel读取数据
要从SocketChannel中读取数据,调用一个read()的方法之一。
首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。
然后,调用SocketChannel.read()。该方法将数据从SocketChannel读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。
写入SocketChannel
写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。
注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法无法保证能写多少字节到SocketChannel。所以,我们重复调用write()直到Buffer没有要写的字节为止。
非阻塞模式
可以设置SocketChannel为非阻塞模式(non-blockingmode).设置之后,就可以在异步模式下调用connect(),read()和write()了。
connect()
如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。
write()
非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。前面已经有例子了,这里就不赘述了。
read()
非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。
非阻塞模式与选择器
非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等。Selector与SocketChannel的搭配使用会在后面详讲。
/** *socketchannel */ @Test publicvoidtest3()throwsIOException{ SocketChannelchannel=SocketChannel.open();//新建服务端 channel.connect(newInetSocketAddress("127.0.0.1",9999));//连接服务端地址 ByteBufferbyteBuffer=ByteBuffer.allocate(1024);//缓冲区 byteBuffer.put("123".getBytes()); byteBuffer.flip();//反转 while(byteBuffer.hasRemaining()){//判断 channel.write(byteBuffer); } }
以上这篇JAVA-NIO之Socket/ServerSocketChannel(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。