今天练习了一下以前学过的NIO编程,写了一个NIO 通信的小示例,希望以后看到这个案例时,可以理解NIO通信的原理
示例代码如下
服务器端
import java.io.IOException;
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.util.Iterator;
import java.util.Set;
/**
* 进行使用Nio套接字来开发我们的tomcat的的服务器的连接操作
* @author Administrator
* 通过调用open方法得到一个ServerSocketChannel通道
* 但是这个通道还没有被绑定地址通过调用调用bind()方法来进行绑定数据
*
*/
public class SocketServer {
public static void start(){
try {
//先进行创建一个转询容器
Selector sel=Selector.open();
//通过open的方法得到nio的套接字通道
ServerSocketChannel server=ServerSocketChannel.open();
//进行绑定我们的地址
server.bind(new InetSocketAddress("localhost",8080),2500);
//进行设置非阻塞的操作的方法
server.configureBlocking(false);
//先进行把我们SSC注册入SelectKey容器当中,同时这个注册服务器通道的感兴趣事件(这个事件有4种)
server.register(sel, SelectionKey.OP_ACCEPT);
while(true){
//进行轮询的桃选已发生的操作感兴趣事件,放入一个selected key集合当中
sel.select(); //是一个阻塞的操作的方法,是一个集合
//进行得到精选key的集合
Set<SelectionKey> set=sel.selectedKeys();
//进行遍历所以的发生的key
Iterator<SelectionKey> it=set.iterator();
while(it.hasNext()){
//得到桃选的key
SelectionKey key=it.next();
//判断这个key是否为服务器的连接方法,如果是则进行连接,得到客户端的通道
if(key.isAcceptable()){
ServerSocketChannel sch=(ServerSocketChannel)key.channel();
//进行接收请求然后进行注册
SocketChannel ch=sch.accept();
//这个也要进行配置我们非阻塞模式
ch.configureBlocking(false);
//然后进行客户端的注册的感兴趣事件
ch.register(sel,SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}
//如果这个是一个读请求,那么则
if(key.isReadable()){
//进行得到客户端的通道
SocketChannel sc=(SocketChannel) key.channel();
//进行读取数据
String str=readFormClient(sc);
System.out.println("from client: "+str);
}
if(key.isWritable()){
ByteBuffer buffer=ByteBuffer.allocate(1024);
buffer.put("数据从服务器发送....".getBytes());
//进行写数据
SocketChannel sc=(SocketChannel)key.channel();
buffer.flip();
sc.write(buffer);
buffer.clear();
}
if(key.isConnectable()){
System.out.println("client connectable");
}
}
//进行移除这个key数据
it.remove();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String readFormClient(SocketChannel sc){
ByteBuffer buffer=ByteBuffer.allocate(1024);
String str=null;
try {
int len=sc.read(buffer);
if(len==-1){
System.out.println("from client:数据已经读取完成...");
}else if(len>0) {
//进行压缩
buffer.flip();
str=new String(buffer.array(),0,buffer.limit());
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
return str.trim();
}
}
服务器的main方法如下:
/**
* 我们的NIO的启动类
* @author Administrator
*
*/
public class Bootstrap {
public static void main(String[] args) {
//网络Socket通信
SocketServer.start();
}
}
客户端代码如下:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SocketChannel;
public class SocketChannelClient {
public static void main(String[] args) {
// 先注册轮询
try {
//Selector selector = Selector.open();
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 创建一个输入流通道
ReadableByteChannel incha = Channels.newChannel(System.in);
// 进行向服务器连接
SocketChannel sc = null;
sc = SocketChannel.open(new InetSocketAddress("localhost", 8080));
sc.configureBlocking(false);
// 进行连接操作
// sc.connect(new InetSocketAddress("localhsot",8080));
while (!sc.finishConnect()) {
}
// 进行从客户端输入数据,然后输出数据
while (true) {
incha.read(buffer);
buffer.flip();
sc.write(buffer);
buffer.clear();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
客户端代码二如下:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SocketChannelClient2 {
public static void main(String[] args) {
try {
// 先注册轮询
Selector sel = Selector.open();
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 创建一个输入流通道
ReadableByteChannel incha = Channels.newChannel(System.in);
// 进行向服务器连接
SocketChannel sc = null;
sc = SocketChannel.open(new InetSocketAddress("localhost", 8080));
sc.configureBlocking(false);
while (!sc.finishConnect()) {
}
// 进行连接操作
// sc.connect(new InetSocketAddress("localhsot",8080));
//进行注册
sc.register(sel,SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE);
// 进行从客户端输入数据,然后输出数据
while (true) {
//进行挑选操作
sel.select();
Iterator<SelectionKey> it=sel.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey key=it.next();
if(key.isConnectable()){
//进行连接服务器
System.out.println("连接服务器...");
}
if(key.isWritable()){
//得到通道
sc=(SocketChannel) key.channel();
System.out.println("输入你要发送的数据:");
incha.read(buffer);
buffer.flip();
sc.write(buffer);
buffer.clear();
}
if(key.isReadable()){
//进行读取数据通道
sc=(SocketChannel) key.channel();
//buffer.clear();
int len=sc.read(buffer);
if(len==-1){
System.out.println("到文件未了...");
}else if(len>0){
buffer.flip();
String str=new String(buffer.array(),0,buffer.limit()).trim();
buffer.clear();
System.out.println("from server:"+str);
}
}
it.remove();
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}