服务端代码
package net.nio;
import java.io.ByteArrayOutputStream;
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;
public class MyServer {
/**
* @Title: 使用NIO实现Socket通信服务器端
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Selector selector = null;
ServerSocketChannel serverSocketChannel = null;
try
{
//开启IO多路复用轮询
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);//必须配置为非阻塞
serverSocketChannel.socket().setReuseAddress(true);//设置当连接处于超时状态时,是否允许新的连接使用旧的连接端口
serverSocketChannel.socket().bind(new InetSocketAddress(10000));//绑定服务器本地地址和端口
//在多路复用轮询器上注册操作
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("server is ready.............");
while(selector.select()>0){
//取得就绪操作
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey readyKey = it.next();
it.remove();
execute((ServerSocketChannel)readyKey.channel());
}
}
System.out.println("server is over.............");
}catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}finally{
try {
selector.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}
try {
serverSocketChannel.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}
}
}
/***/
private static void execute(ServerSocketChannel serverSocketChannel)throws IOException{
SocketChannel socketChannel = null;
try{
//收到客户端请求信息
socketChannel = serverSocketChannel.accept();
RequestObject requestObject = receiveData(socketChannel);
System.out.println("receive from Client:"+requestObject.toString());
//发生响应信息到客户端
ResponseObject responseObject = new ResponseObject("response for "+requestObject.getName(),
"response for "+requestObject.getValue());
sendData(socketChannel,responseObject);
}finally{
socketChannel.close();
}
}
private static RequestObject receiveData(SocketChannel socketChannel)throws IOException{
RequestObject requestObject = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteBuffer buffer = ByteBuffer.allocate(1024);
try{
byte[] bytes;
int size = 0;
while((size=socketChannel.read(buffer))>=0){
//反转指针,由写状态到读状态
buffer.flip();
bytes = new byte[size];
buffer.get(bytes);
bos.write(bytes);
buffer.clear();
}
bytes = bos.toByteArray();
Object result = ClassUtil.bytes2Object(bytes);
requestObject = (RequestObject)result;
}finally{
bos.close();
}
return requestObject;
}
private static void sendData(SocketChannel socketChannel,ResponseObject responseObject)throws IOException{
byte[] bytes = ClassUtil.object2Bytes(responseObject);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
socketChannel.write(buffer);
}
}
客户端调用代码
package net.nio;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class MyClient {
/**
* @Title: NIO客户端,发生消息
* @Description: 启动100个线程给服务端发消息
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=0;i<100;i++){
final int idx = i;
new Thread(new MyRunnable(idx)).start();
}
}
}
class MyRunnable implements Runnable{
private final int idx;
public MyRunnable(int idx){
this.idx = idx;
}
@Override
public void run() {
SocketChannel socketChannel = null;
try{
//连接服务器
socketChannel = SocketChannel.open();
SocketAddress remoteAddress = new InetSocketAddress("127.0.0.1",10000);
socketChannel.connect(remoteAddress);
//发送请求
RequestObject requestObject = new RequestObject("request_"+idx,"request_"+idx);
sendData(socketChannel,requestObject);
//接收响应
ResponseObject responseObject = receiveData(socketChannel);
System.out.println("reveive from server:"+responseObject.toString());
}catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}finally{
try {
socketChannel.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}
}
}
private void sendData(SocketChannel socketChannel,RequestObject requestObject)throws IOException{
byte[] bytes = ClassUtil.object2Bytes(requestObject);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
socketChannel.write(buffer);
//结束输出
socketChannel.socket().shutdownOutput();
}
private ResponseObject receiveData(SocketChannel socketChannel)throws IOException{
ResponseObject responseObject = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try{
ByteBuffer buffer = ByteBuffer.allocate(1024);
byte[] bytes;
int size=0;
while((size=socketChannel.read(buffer))>=0){
buffer.flip();
bytes = new byte[size];
buffer.get(bytes);
bos.write(bytes);
buffer.clear();
}
bytes = bos.toByteArray();
responseObject = (ResponseObject) ClassUtil.bytes2Object(bytes);
//结束读入
socketChannel.socket().shutdownInput();
}finally{
bos.close();
}
return responseObject;
}
}
工具类
package net.nio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* 操作class的工具类,包括序列化,反序列化,获取类信息
* */
public class ClassUtil {
//用于缓存类的Field信息
private static ConcurrentHashMap<String, List<Field>> classFieldMap = new ConcurrentHashMap<String,List<Field>>();
//用于缓存类的Field信息
private static ConcurrentHashMap<String,Method[]> classMethodMap = new ConcurrentHashMap<String,Method[]>();
/**
* 序列化
* @param object 需要序列化的对象
* */
public static byte[] object2Bytes(Object object){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try{
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}finally{
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}
}
return baos.toByteArray();
}
/**
* 反序列化
* @param bytes 需要反序列化成对象的字节数组
* */
public static Object bytes2Object(byte[] bytes){
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream(bis);
Object object = ois.readObject();
return object;
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage(),e);
}finally{
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(),e);
}
}
}
}
}
ResponseObject和RequestObject就是简单的java bean,因为字数研制,就不给出了。