NIO系列(四)——socket通道和serversocket通道

来源:互联网 发布:一元淘宝秒杀 编辑:程序博客网 时间:2024/04/20 03:11

SocketChannel

SocketChannel是一个连接到tcp网络套接字的通道。可以通过以下2中方式创建

1.打开一个SocketChannel并连接到互联网上的某台服务器。

SocketChannel client = SocketChannel.open(new InetSocketAddress("127.0.0.1",10699));

2.ServerSocketChannel获得一个网络连接。

SocketChannel connctClient = server.accept();

创建SocketChannel

通过SocketChannel.Open()方法创建通道,open()方法可以传入连接对象的参数。

SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("192.168.1.107",9999));

关闭SocketChannel

通过close()方法关闭通道。

socketChannel.close();

socketChannel接收信息

可以通过read()方法把通道数据读到缓存中。

ByteBuffer bBuffer = ByteBuffer.allocate(48);int readSize;do {    readSize = socketChannel.read(bBuffer);    bBuffer.flip();    System.out.println(Charset.forName("UTF-8").decode(bBuffer));    bBuffer.clear();} while (readSize != -1);

read()返回的int值表示读到缓存数据的长度,当返回值为-1时,表示到了流的末尾。

SocketChannel发送信息

通过write()方法将缓存数据写入到通道内,write()无法保证一次向通道中写入多少数据,所以要循环判断hasRemainning(),直到没有数据写入。

ByteBuffer bBuffer = ByteBuffer.wrap(("服务器" + server + "连接成功").getBytes());while (bBuffer.hasRemaining()){    socketChannel.write(bBuffer);}

非阻塞设置

SocketChannel可以通过configureBlocking()方法设置成非阻塞。

socketChannel.configureBlocking(false);

例子

这个例子是与192.168.1.107:9999建立连接并接收一次发送数据。

public voidtestClient() {    try {       SocketChannelsocketChannel= SocketChannel.open();       socketChannel.configureBlocking(false);       socketChannel.connect(new InetSocketAddress("192.168.1.107",9999));       ByteBufferbBuffer= ByteBuffer.allocate(48);       int readSize;       do {           readSize = socketChannel.read(bBuffer);           bBuffer.flip();           System.out.println(Charset.forName("UTF-8").decode(bBuffer));           bBuffer.clear();       }while(readSize!= -1);       socketChannel.close();    }catch(IOException e) {       e.printStackTrace();    }}

ServerSocketChannel

Java NIO的ServerSocketChannel是一个可以监听新进来的TCP连接的通道,就像标准IO的ServerSocket一样。

创建ServerSocketChannel

通过ServerSocketChannel.open()创建通道

ServerSocketChannel server = ServerSocketChannel.open();server.socket().bind(new InetSocketAddress(9999));

server.socket().bind(SocketAddressendpoint, int backlog)可以传两个参数,第二个参数是,限制最大连接数。

获得连接

通过accept()方法,获得socket连接

SocketChannel socketChannel = server.accept();

发送数据和接收数据都通过SocketChannel进行。

关闭ServerSocketChannel

通过close()方法关闭通道

server.close();

非阻塞设置

ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept会立即返回,所以要判断SocketChannel是否为空。

server.configureBlocking(false);while (true){    SocketChannelsocketChannel= server.accept();    if (socketChannel != null) {          }}

例子

这个例子先绑定监听9999端口,但有socket连接时,会发送一条数据。

public voidtestServer() {    try {       ServerSocketChannelserver= ServerSocketChannel.open();       server.socket().bind(newInetSocketAddress(9999));       System.out.println("服务端启动成功");       server.configureBlocking(false);       while (true) {           SocketChannelsocketChannel= server.accept();           if (socketChannel != null) {              System.out.println(socketChannel + "连接成功");              ByteBufferbBuffer= ByteBuffer.wrap(("服务器" + server + "连接成功").getBytes());              while (bBuffer.hasRemaining()) {                  socketChannel.write(bBuffer);              }           }       }    }catch(IOException e) {       e.printStackTrace();    }}