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();
}
分享到:
相关推荐
使用`ServerSocketChannel`,我们可以设置监听指定的端口,并在有新的连接请求时,通过调用`accept()`方法来接受连接并返回一个新的`SocketChannel`对象,这个`SocketChannel`代表了与客户端建立的具体连接。...
4. 使用SocketFactory创建一个`SSLSocketChannel`,并将其与普通的SocketChannel关联起来。 5. 初始化SSL会话,包括握手过程,这可能涉及到多次读写操作,直到握手成功。 6. 在会话建立后,就可以使用非阻塞的`read...
2. 打开SocketChannel:使用ServerSocketChannel.bind()方法监听指定端口,然后调用accept()方法获取连接的SocketChannel。 3. 注册Selector:使用SocketChannel的register()方法,将通道注册到Selector上,同时指定...
与传统的Socket相比,SocketChannel允许我们在读写操作上使用非阻塞模式,从而提高程序的并发性能。 2. **ServerSocketChannel**:这个类代表了一个服务器端的套接字,用于监听客户端的连接请求。创建...
本篇文章将详细解析如何使用非阻塞ServerSocketChannel和SocketChannel来替代传统的ServerSocket和Socket。 **1. 阻塞与非阻塞I/O** 在阻塞I/O模型中,当一个线程调用read或write方法时,如果数据没有准备好或者...
一个 Java SocketChannel 实现,它使用提供的 Proxy 实例通过提供的代理建立网络连接。 SocketChannel 是通过表面下的 Socket 实例实现的。 限制 此实现目前仅支持阻塞模式。 请注意,这是 SocketChannel 实例的默认...
NIO SSL 与阻塞IO不同,JVM不提供扩展基本套接字通道类的标准SSLSocketChannel和SSLServerSocketChannel类。 相反,必须使用手动编排SSL交换。...使用SSLSocketChannel 由普通的SocketChannel和必要的SSL相关信息
通过使用Selector,我们可以设计出一种选择器模式,将多个通道注册到同一个选择器上,然后在单个线程中轮询选择器,处理那些准备好的通道,从而实现高并发的网络服务。 总的来说,本教程将围绕ServerSocketChannel...
使用socket channel 连接服务器,断线重连,发送保活等的封装类。 Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的...
没有使用其他jar包 主要功能: 1、广场群聊,即发送的消息所有在线的人都能看到 2、聊天室群聊,可以创建聊天室,进入聊天室的人可以在里面聊天,创建的人或者是第一个人为管理员,拥有踢人的权限;广场上有一个...
本主题聚焦于“高级Socket通信”,特别是涉及到使用SocketChannel的实现方式。SocketChannel是Java NIO(非阻塞I/O)框架的一部分,它提供了一种更高效、灵活的方式来处理网络连接。 首先,我们要理解Socket的基本...
SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); // 连接到服务器 InetSocketAddress serverAddress = new InetSocketAddress("localhost", 8080); ...
- **读取数据**:使用`socketChannel.read(ByteBuffer buffer)`从SocketChannel中读取数据。 - **发送数据**:使用`socketChannel.write(ByteBuffer buffer)`向SocketChannel中写入数据。 2. **ByteBuffer**:它...
在这个案例中,我们将讨论如何使用Socket来实现一个简单的聊天室功能,包括服务器端和客户端的实现。 首先,我们要理解Socket的基本概念。Socket是网络通信中的一个抽象接口,可以看作是两台计算机之间的通信通道。...
- 当有客户端连接时,创建一个新的`SocketChannel`来处理该连接上的通信。 ```java NioServerSocketChannel server = NioServerSocketChannel.open(); server.bind(new InetSocketAddress("localhost", 4444)); ...
客户端通常使用SocketChannel与服务器建立连接,并通过该通道发送和接收数据。在发送数据前,需要先将数据写入Buffer,然后调用`SocketChannel.write()`方法。接收到服务器响应后,使用`SocketChannel.read()`读取...
- 客户端首先需要创建一个SocketChannel,通过`SocketChannel.open()`打开,并使用`SocketChannel.connect(SocketAddress)`连接到服务器端的地址。 - 同样,客户端也需要使用缓冲区进行数据的读写操作。 - 如果...
- 使用 `SocketChannel` 进行网络通信。 - 设置目标服务器地址和端口。 - 尝试建立非阻塞连接。 - 发送用户名到服务器。 #### 3. `inputName` 方法 - 使用 `JOptionPane.showInputDialog` 获取用户的输入,并设置为...
它们分别展示了如何使用`SocketChannel`实现客户端和服务器端的非阻塞IO通信。 在`SocketChannelClient.java`中,客户端通常会首先创建一个`SocketChannel`,然后打开一个连接到服务器的通道。接着,它会创建一个`...