Java NIO 服务器端简单实现例子
注意:
1.NIO主要用于服务端,若用来客户端相对于它带来的额外复杂性有点不值得。
2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。
3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。
代码:
与之配合的客户端代码,没有采用NIO方式。
服务器端的输出:
客户端的输出:
1.NIO主要用于服务端,若用来客户端相对于它带来的额外复杂性有点不值得。
2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。
3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。
代码:
package
com.heyang.biz.server.test.nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* NIO 服务器
* 说明:
* 作者:何杨([email protected])
* 创建时间:2011-1-3 下午12:09:02
* 修改时间:2011-1-3 下午12:09:02
*/
public class NIOServer{
// 本地字符集
private static final String LocalCharsetName = " gb2312 " ;
// 本地服务器监听的端口
private static final int Listenning_Port = 8888 ;
// 缓冲区大小
private static final int Buffer_Size = 1024 ;
// 超时时间,单位毫秒
private static final int TimeOut = 3000 ;
public static void main(String[] args) throws Exception{
// 创建一个在本地端口进行监听的服务Socket信道.并设置为非阻塞方式
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.socket().bind( new InetSocketAddress(Listenning_Port));
serverChannel.configureBlocking( false );
// 创建一个选择器并将serverChannel注册到它上面
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while ( true ){
// 等待某个信道就绪
if (selector.select(TimeOut) == 0 ){
System.out.println( " . " );
continue ;
}
// 获得就绪信道的键迭代器
Iterator < SelectionKey > keyIter = selector.selectedKeys().iterator();
// 使用迭代器进行遍历就绪信道
while (keyIter.hasNext()){
SelectionKey key = keyIter.next();
// 这种情况是有客户端连接过来,准备一个clientChannel与之通信
if (key.isAcceptable()){
SocketChannel clientChannel = ((ServerSocketChannel)key.channel()).accept();
clientChannel.configureBlocking( false );
clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
}
// 客户端有写入时
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();
// 将获得字节字符串(使用Charset进行解码)
String receivedString = Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println( " 接收到信息: " + receivedString);
// 准备发送的文本
String sendString = " 你好,客户端. 已经收到你的信息 " + receivedString;
// 将要发送的字符串编码(使用Charset进行编码)后再进行包装
buffer = ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
// 发送回去
clientChannel.write(buffer);
// 设置为下一次读取或是写入做准备
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
keyIter.remove();
}
}
}
}
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* NIO 服务器
* 说明:
* 作者:何杨([email protected])
* 创建时间:2011-1-3 下午12:09:02
* 修改时间:2011-1-3 下午12:09:02
*/
public class NIOServer{
// 本地字符集
private static final String LocalCharsetName = " gb2312 " ;
// 本地服务器监听的端口
private static final int Listenning_Port = 8888 ;
// 缓冲区大小
private static final int Buffer_Size = 1024 ;
// 超时时间,单位毫秒
private static final int TimeOut = 3000 ;
public static void main(String[] args) throws Exception{
// 创建一个在本地端口进行监听的服务Socket信道.并设置为非阻塞方式
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.socket().bind( new InetSocketAddress(Listenning_Port));
serverChannel.configureBlocking( false );
// 创建一个选择器并将serverChannel注册到它上面
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while ( true ){
// 等待某个信道就绪
if (selector.select(TimeOut) == 0 ){
System.out.println( " . " );
continue ;
}
// 获得就绪信道的键迭代器
Iterator < SelectionKey > keyIter = selector.selectedKeys().iterator();
// 使用迭代器进行遍历就绪信道
while (keyIter.hasNext()){
SelectionKey key = keyIter.next();
// 这种情况是有客户端连接过来,准备一个clientChannel与之通信
if (key.isAcceptable()){
SocketChannel clientChannel = ((ServerSocketChannel)key.channel()).accept();
clientChannel.configureBlocking( false );
clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
}
// 客户端有写入时
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();
// 将获得字节字符串(使用Charset进行解码)
String receivedString = Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println( " 接收到信息: " + receivedString);
// 准备发送的文本
String sendString = " 你好,客户端. 已经收到你的信息 " + receivedString;
// 将要发送的字符串编码(使用Charset进行编码)后再进行包装
buffer = ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
// 发送回去
clientChannel.write(buffer);
// 设置为下一次读取或是写入做准备
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
keyIter.remove();
}
}
}
}
与之配合的客户端代码,没有采用NIO方式。
package
com.heyang.biz.server.test.nio;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TestClient{
public static void main(String[] args) throws Exception{
Socket s = new Socket( " 127.0.0.1 " , 8888 );
InputStream inStram = s.getInputStream();
OutputStream outStream = s.getOutputStream();
// 输出
PrintWriter out = new PrintWriter(outStream, true );
out.print( " getPublicKey你好! " );
out.flush();
s.shutdownOutput(); // 输出结束
// 输入
Scanner in = new Scanner(inStram);
StringBuilder sb = new StringBuilder();
while (in.hasNextLine()){
String line = in.nextLine();
sb.append(line);
}
String response = sb.toString();
System.out.println( " response= " + response);
}
}
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TestClient{
public static void main(String[] args) throws Exception{
Socket s = new Socket( " 127.0.0.1 " , 8888 );
InputStream inStram = s.getInputStream();
OutputStream outStream = s.getOutputStream();
// 输出
PrintWriter out = new PrintWriter(outStream, true );
out.print( " getPublicKey你好! " );
out.flush();
s.shutdownOutput(); // 输出结束
// 输入
Scanner in = new Scanner(inStram);
StringBuilder sb = new StringBuilder();
while (in.hasNextLine()){
String line = in.nextLine();
sb.append(line);
}
String response = sb.toString();
System.out.println( " response= " + response);
}
}
服务器端的输出:
.
接收到信息:getPublicKey你好!
.
接收到信息:getPublicKey你好!
.
客户端的输出:
response=你好,客户端. 已经收到你的信息getPublicKey你好!