NIO通道客户端:
实现步骤
- 打开通道
- 指定IP和端口号
- 写出数据
- 读取服务器写回的数据
- 释放资源
public static void main(String[] args) throws Exception {
//打开通道
SocketChannel open = SocketChannel.open ();
//指定IP和端口号
open.connect (new InetSocketAddress ("192.168.10.52", 4399));
ByteBuffer buffer = ByteBuffer.wrap ("你艾希我奶妈".getBytes ());
open.write (buffer);
open.shutdownOutput ();//告诉服务器数据已经把数据发送完毕
//读取服务器回送的消息
ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024);
buffer.flip ();
int len;
while((len = open.read(byteBuffer2)) != -1){
System.out.println("客户端接收回写数据");
String s = new String (byteBuffer2.array (), 0, len);
System.out.println (s);
byteBuffer2.clear();
}
open.close();
}
NIO通道服务端:
实现步骤
-
打开一个服务端通道(open)
-
绑定对应的端口号
-
通道默认是阻塞的,需要设置为非阻塞
-
打开一个选择器(门卫大爷)
-
将选择器绑定服务端通道,并监视服务端是否准备好
-
如果有客户端来连接了,大爷会遍历所有的服务端通道,谁准备好了,就让谁来连接
连接后,在服务端通道内部,再创建一个客户端延伸通道 -
如果客户端把数据传递过来了,大爷会遍历所有的延伸通道,谁准备好了,谁去接收数据
public static void main(String[] args) throws IOException {
//1.打开服务器通道,绑定通道端口
ServerSocketChannel open = ServerSocketChannel.open ();
ServerSocketChannel bind = open.bind (new InetSocketAddress (4399));
//2.设置f服务通道为非堵塞,默认为堵塞
open.configureBlocking (false);
// SocketChannel accept1 = open.accept ();
//3.打开选择器 Selector
Selector selector = Selector.open ();
//4.绑定选择器和服务通道状态
open.register (selector, SelectionKey.OP_ACCEPT);
while (true){
//6.连接的用户数,表示此时有多少个客户端来连接
int count = selector.select ();
if(count!=0){
System.out.println ("有客户端来连接");
//7.用集合存储所有用户的通道的状态,遍历所有的服务端通道状态信息
Set<SelectionKey> selectionKeys = selector.selectedKeys ();
Iterator<SelectionKey> iterator = selectionKeys.iterator ();
while (iterator.hasNext ()){
//8.获取到当前通道的状态
SelectionKey next = iterator.next ();
if(next.isAcceptable ()){
//9.获取到一个就绪的通道,强行转换为ServerSocketChannel
ServerSocketChannel channel =(ServerSocketChannel) next.channel ();
//10.在服务端通道内部,再创建一个客户端通道,相当于是客户端通道的延伸,接受客户端发送的信息
SocketChannel accept = channel.accept ();
//将客户端通道设置为非堵塞
accept.configureBlocking (false);
//4.绑定选择器和改变服务通道状态
accept.register(selector,SelectionKey.OP_READ);
}else if(next.isReadable ()){
//需要读取 客户端中的数据
SocketChannel channel =(SocketChannel) next.channel ();
ByteBuffer arr = ByteBuffer.allocate (1024);
byte[] array = arr.array ();
while (true){
int len=channel.read (arr);
if(len==-1){
//读取到数据的最后没有就返回-1,改变通道状态
channel.register(selector,SelectionKey.OP_WRITE);
break;
}else if(len==0){
break;
}else if(len>0){
System.out.println("服务端接收客户端发送数据");
String msg = new String (array, 0, len);
String ip = channel.getRemoteAddress ().toString ();
System.out.println (ip+""+msg);
}
}
}else if(next.isWritable ()){
SocketChannel channel =(SocketChannel) next.channel ();
ByteBuffer wrap = ByteBuffer.wrap ("宝塔镇河妖".getBytes ());
channel.write (wrap);
channel.close ();
}
}
iterator.remove ();
}
}
}