首页

基于JAVA NIO实现的简单服务端Server和客户端Client通信代码示例说明

标签:nio通信,mina,JAVA NIO,非阻塞io,消息通信机制,客户服务端会话代码示例     发布时间:2018-10-07   

一、前言

该项目源码基于java nio的非阻塞I/O的消息事件的方式进行通信,主要包含Server服务端通信代码和Client客户端代码(完整项目源码参见相关资源下载页面)。

二、代码说明

1. Server服务端代码

import java.io.IOException;@b@import java.net.InetSocketAddress;@b@import java.nio.ByteBuffer;@b@import java.nio.CharBuffer;@b@import java.nio.channels.Selector;@b@import java.nio.channels.ServerSocketChannel;@b@import java.nio.channels.SelectionKey;@b@import java.nio.channels.SocketChannel;@b@import java.nio.charset.Charset;@b@import java.nio.charset.CharsetDecoder;@b@import java.nio.charset.CharsetEncoder;@b@import java.util.Iterator;@b@@b@public class Server {@b@	private static final int SERVERPORT=8890;@b@	public static void main(String[] args) {@b@		Selector selector = null;@b@		ServerSocketChannel server = null;@b@		try{@b@			selector = Selector.open();@b@			server = ServerSocketChannel.open();@b@			InetSocketAddress ip = new InetSocketAddress(SERVERPORT);@b@			server.socket().bind(ip);@b@			server.configureBlocking(false);@b@			server.register(selector,SelectionKey.OP_ACCEPT);@b@			System.out.println("服务器开始接受客户端连接");@b@   @b@			while(true){@b@//				select@b@				try {@b@					selector.select();@b@				} catch (Exception e) {@b@					// TODO: handle exception@b@//					System.out.println("select 错误");@b@				}@b@				Iterator<SelectionKey>it = selector.selectedKeys().iterator();@b@//				deal everyone@b@				while(it.hasNext()){@b@					SelectionKey key = it.next();@b@					it.remove();@b@//					acceptable@b@					if(key.isAcceptable()){@b@						ServerSocketChannel server2 = (ServerSocketChannel)key.channel();@b@						SocketChannel channel = server2.accept();@b@						channel.configureBlocking(false);@b@						channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);@b@						System.out.println("客户端:"@b@								+ channel.socket().getInetAddress().getHostName() + ":"@b@								+ channel.socket().getPort() + " 连接上了");@b@					}@b@//					readable@b@					if(key.isReadable()){@b@//						System.out.println("可读");@b@						SocketChannel channel = (SocketChannel)key.channel();@b@						CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();@b@						ByteBuffer buffer = ByteBuffer.allocate(50);@b@						try{@b@							channel.read(buffer);@b@						}catch(IOException e){@b@//							客户端异常断开连接@b@							System.out.println("客户端:"@b@									+ channel.socket().getInetAddress().getHostName() + ":"@b@									+ channel.socket().getPort() + " 已断开连接");@b@							channel.close();@b@							continue;@b@						}@b@						buffer.flip();@b@						String msg = decoder.decode(buffer).toString();@b@@b@						if (msg.equals("退出!@#$%")) {@b@//							客户端主动断开连接@b@							System.out.println("客户端:"@b@									+ channel.socket().getInetAddress().getHostName() + ":"@b@									+ channel.socket().getPort() + " 已断开连接");@b@							channel.close();@b@							continue;@b@						}@b@						System.out.println(@b@								channel.socket().getInetAddress().getHostName() + ":"@b@								+ channel.socket().getPort() + ":" + msg);@b@						@b@						if (key.isWritable()) {@b@//							System.out.println("可写");@b@							CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();@b@							try {@b@								channel.write(encoder.encode(CharBuffer.wrap("server receive your message ")));@b@							} catch (IOException e) {@b@								// TODO: handle exception@b@								System.out.println("写入io错误");@b@							}@b@						}@b@					}@b@				}@b@			}@b@		}catch(IOException e){@b@			e.printStackTrace();@b@		}@b@		finally{@b@			try{@b@				selector.close();@b@				server.close();@b@			}catch(IOException e){}@b@		}@b@	}@b@}

2. Client客户端代码

import java.io.*;@b@@b@public class Client {@b@@b@	public static void main(String[] args) {@b@		ClientThread client = new ClientThread();@b@		client.start();@b@		BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));@b@		try{@b@			String readline;@b@			while((readline = sin.readLine())!=null){@b@				if(readline.equals("bye")){@b@					client.close();@b@					System.exit(0);@b@				}@b@				client.send(readline);@b@			}@b@		}catch(IOException e){@b@			e.printStackTrace();@b@		}@b@	}@b@}
import java.io.IOException;@b@import java.net.InetSocketAddress;@b@import java.nio.ByteBuffer;@b@import java.nio.CharBuffer;@b@import java.nio.channels.Selector;@b@import java.nio.channels.SelectionKey;@b@import java.nio.channels.SocketChannel;@b@import java.nio.charset.Charset;@b@import java.nio.charset.CharsetDecoder;@b@import java.nio.charset.CharsetEncoder;@b@import java.util.Iterator;@b@@b@public class ClientThread extends Thread {@b@@b@	private CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();@b@	private CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();@b@	private Selector selector = null;@b@	private SocketChannel socket = null;@b@	private SelectionKey clientKey = null;@b@@b@	public ClientThread(){@b@		try{@b@			selector = Selector.open();@b@			socket = SocketChannel.open();@b@			socket.configureBlocking(false);@b@			clientKey = socket.register(selector, SelectionKey.OP_CONNECT);@b@			InetSocketAddress ip = new InetSocketAddress("localhost",8890);@b@			socket.connect(ip);@b@		}catch(IOException e){@b@			e.printStackTrace();@b@		}@b@	}@b@	public void run(){@b@		try{@b@			while(true){@b@				selector.select(1);@b@				Iterator<SelectionKey>it = selector.selectedKeys().iterator();@b@				while(it.hasNext()){@b@					SelectionKey key = it.next();@b@					it.remove();@b@					if(key.isConnectable()){@b@						SocketChannel channel = (SocketChannel)key.channel();@b@						if(channel.isConnectionPending())@b@							channel.finishConnect();@b@						channel.register(selector, SelectionKey.OP_READ);@b@						System.out.println("连接服务器端成功!");@b@					}else if(key.isReadable()){@b@						SocketChannel channel = (SocketChannel)key.channel();@b@						ByteBuffer buffer = ByteBuffer.allocate(50);@b@						try{@b@							channel.read(buffer);@b@						}catch(IOException e){@b@							System.out.println("与服务器:"@b@									+ channel.socket().getInetAddress().getHostName() + ":"@b@									+ channel.socket().getPort() + "的连接已断开");@b@							channel.close();@b@							continue;//这一句是为了让你看到打印信息@b@						}@b@						buffer.flip();@b@						String msg = decoder.decode(buffer).toString();@b@						System.out.println(@b@								channel.socket().getInetAddress().getHostName() + ":"@b@								+ channel.socket().getPort() + ":" + msg);@b@					}@b@				}@b@			}@b@   @b@		}catch(IOException e){@b@			e.printStackTrace();@b@		}@b@		finally{@b@			try{@b@				selector.close();@b@				socket.close();@b@			}catch(IOException e){}@b@		}@b@	}@b@@b@	public void send(String msg){@b@		try{@b@			SocketChannel client = (SocketChannel)clientKey.channel();@b@			client.write(encoder.encode(CharBuffer.wrap(msg)));@b@		}catch(Exception e){@b@			System.out.println("发送信息失败");@b@			e.printStackTrace();@b@		}@b@	}@b@@b@	public void close(){@b@		try{@b@			selector.close();@b@			socket.close();@b@		}catch(IOException e){@b@			e.printStackTrace();@b@		}@b@	}@b@}