1.服务器端while(true) 一直等待client端来连接。
基本步骤为:
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(5200));
Selector select = Selector.open();
server.register(select, SelectionKey.OP_ACCEPT);
声明一个等待客户端的服务器。
select.select();
Set readkeys = select.selectedKeys();
Iterator iterator = readkeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
if (key.isAcceptable()) {
SocketChannel client = ((ServerSocketChannel) key.channel()).accept();
System.out.println("Accept connection from: " + client);
client.configureBlocking(false);
client.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
if (key.isReadable()) {
// 获得与客户端通信的信道
SocketChannel clientChannel = (SocketChannel) key.channel();
// 得到并清空缓冲区
ByteBuffer buffer = (ByteBuffer) key.attachment();
buffer.clear();
// 读取信息获得读取的字节数
long bytesRead = clientChannel.read(buffer);
if (bytesRead == -1) {
// 没有读取到内容的情况
clientChannel.close();
} else {
// 将缓冲区准备为数据传出状态
buffer.flip();
// 将字节转化为为UTF-16的字符串
String receivedString = Charset.forName("UTF-16").newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println("接收到来自" + clientChannel.socket().getRemoteSocketAddress() + "的信息:" + receivedString);
// 准备发送的文本
String sendString = "你好,客户端. @" + new Date().toString() + ",已经收到你的信息" + receivedString;
buffer = ByteBuffer.wrap(sendString.getBytes("UTF-16"));
clientChannel.write(buffer);
// 设置为下一次读取或是写入做准备
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
if (key.isWritable())
{
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer writeBuffer=ByteBuffer.wrap("我的程序员之道".getBytes("UTF-16"));
sc.write(writeBuffer);
}
key.channel().close();
}
遍历键集,然后判断键的可读可写等做不同的操作
客户端建立一个线程,等待服务器端的回应:
1.建立基本的SocketChannel
SocketChannel sc = SocketChannel.open(new InetSocketAddress("172.16.22.11", 5200));
//打开一个SocketChannel并连接到服务器
sc.configureBlocking(false);
Selector selector = Selector.open();
sc.register(selector, SelectionKey.OP_READ);
在实现Runable的run方法里遍历键集,判断做不同的操作:
while (selector.select() > 0) {
// 遍历每个有可用IO操作Channel对应的SelectionKey
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey sk = (SelectionKey) it.next();
it.remove();
// 如果该SelectionKey对应的Channel中有可读的数据
if (sk.isReadable()) {
// 使用NIO读取Channel中的数据
SocketChannel socketChannel = (SocketChannel) sk.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer);
buffer.flip();
// 将字节转化为为UTF-16的字符串
String receivedString = Charset.forName("UTF-16").newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println("接收到来自服务器" + socketChannel.socket().getRemoteSocketAddress() + "的信息:" + receivedString);
// 为下一次读取作准备
// sk.interestOps(SelectionKey.OP_READ);//将键设为可读
}
if (sk.isWritable()) {
SocketChannel socketChannel = (SocketChannel) sk.channel();
ByteBuffer writeBuffer = ByteBuffer.wrap("我的程序员之道".getBytes("UTF-16"));
socketChannel.write(writeBuffer);
}
// 删除正在处理的SelectionKey
selector.selectedKeys().remove(sk);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
分享到:
相关推荐
java的ServerSocketChannel与SocketChannel的使用
SocketChannel非阻塞网络编程
一个关于SocketChannel、ServerSocketChannel、Selector的综合案例
这是一个非阻塞通信学习的基础模板,让你轻松掌握非阻塞通信。里面还包含了可运行的jar包,可以抢先体验效果哦~_~
一个 Java SocketChannel 实现,它使用提供的 Proxy 实例通过提供的代理建立网络连接。 SocketChannel 是通过表面下的 Socket 实例实现的。 限制 此实现目前仅支持阻塞模式。 请注意,这是 SocketChannel 实例的默认...
NIO SSL 与阻塞IO不同,JVM不提供扩展基本套接字通道类的标准SSLSocketChannel和SSLServerSocketChannel类。 相反,必须使用手动编排SSL交换。...使用SSLSocketChannel 由普通的SocketChannel和必要的SSL相关信息
NIO(服务端和客户端代码) 博文链接:https://songjianyong.iteye.com/blog/1757406
使用socket channel 连接服务器,断线重连,发送保活等的封装类。 Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的...
没有使用其他jar包 主要功能: 1、广场群聊,即发送的消息所有在线的人都能看到 2、聊天室群聊,可以创建聊天室,进入聊天室的人可以在里面聊天,创建的人或者是第一个人为管理员,拥有踢人的权限;广场上有一个...
【IT十八掌徐培成】Java基础第27天-02.NIO-ServerSocketChannel-SocketChannel.zip
利用Socket实现聊天室实时聊天功能,包含服务器端以及客户端,输入指定IP和端口号进行监控
● SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。 ● Selector:为ServerSocketChannel监控接收连接就绪事件,为SocketChannel监控连接就绪、读就绪和写就绪事件。 ● SelectionKey:代表...
SocketChannel被Selector检查,检查其声称可以接受的状态是否已经产生,如当SocketChannel在向Selector注册是设置了可接受状态为Read,此时当SocketChannel接收到数据后将进入可读状态。 如果需要实现一个线程或...
用JAVA写的一个FPT小程序,可实现简单的Ftp功能,Server端有Ui界面。
1.ServerSocketChannel与SocketChannel通讯 2.java Fork/Join 与ThreadPool使用
java socket 大文件传输,快速传输, 数据包的分片,组装,涉及UDP,TCP传输技术,NIO非阻塞等等,适合对socket编程进一步学习的同学
客户端使用 AsynchronousSocketChannel 和 CompletableFuture 的简单 TCP 客户端
NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册...
实现了客户端和服务器之间的通信,服务器是用socketChannel实现,
1.客户端连接服务端,服务端通过Selector接收到连接请求,将其socketChannel通道保存到通道集合,并触发客户端连接事件 2.客户端发送数据包请求到服务端,服务端将请求的SelectionKey压入“读消息生产者队列”,立即...