Java nio 实现socket异步通信 (对Java nio 实习笔记五中内容做一纠正)
来源:互联网 发布:医院网络割接方案 编辑:程序博客网 时间:2024/06/01 09:19
原始错误版本请看:http://blog.csdn.net/tsyj810883979/article/details/6877216
在原有基础上考虑了编码与解码的问题,还有消息发送的两个重要方法调用疏忽
public abstract int write(ByteBuffer src) 将字节序列从给定的缓冲区中写入此通道。
public abstract int read(ByteBuffer dst) 将字节序列从此通道中读入给定的缓冲区。
下面代码在关闭连接时还有问题,服务器可以与客户端断开,但是客户端断开后没有退出,再次操作会出现异常。
服务器端代码实现:
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.nio.charset.Charset;import java.util.Calendar;import java.util.Iterator;public class TestServer {public static void main(String[] args) {new Thread(new EchoServer(1982)).start();}}class EchoServer implements Runnable {//要监听的端口号private int port;//生成一个信号监视器private Selector s;//读缓冲区private ByteBuffer r_bBuf = ByteBuffer.allocate(1024);private ByteBuffer w_bBuf;public EchoServer(int port) {this.port = port;try {s = Selector.open();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try {//生成一个ServerScoket通道的实例对象,用于侦听可能发生的IO事件ServerSocketChannel ssc = ServerSocketChannel.open();//将该通道设置为异步方式ssc.configureBlocking(false);//绑定到一个指定的端口ssc.socket().bind(new InetSocketAddress(port));//注册特定类型的事件到信号监视器上ssc.register(s, SelectionKey.OP_ACCEPT);System.out.println("The server has been launched...");while(true) {//将会阻塞执行,直到有事件发生s.select();Iterator<SelectionKey> it = s.selectedKeys().iterator();while(it.hasNext()) {SelectionKey key = it.next();//key定义了四种不同形式的操作switch(key.readyOps()) {case SelectionKey.OP_ACCEPT :dealwithAccept(key);break;case SelectionKey.OP_CONNECT :break;case SelectionKey.OP_READ :dealwithRead(key);break;case SelectionKey.OP_WRITE :break;}//处理结束后移除当前事件,以免重复处理it.remove();}}} catch (IOException e) {e.printStackTrace();}}//处理接收连接的事件private void dealwithAccept(SelectionKey key) {try {System.out.println("新的客户端请求连接...");ServerSocketChannel server = (ServerSocketChannel)key.channel();SocketChannel sc = server.accept();sc.configureBlocking(false);//注册读事件sc.register(s, SelectionKey.OP_READ);System.out.println("客户端连接成功...");} catch (IOException e) {e.printStackTrace();}}//处理客户端发来的消息,处理读事件private void dealwithRead(SelectionKey key) {try {SocketChannel sc = (SocketChannel)key.channel();System.out.println("读入数据");r_bBuf.clear();//将字节序列从此通道中读入给定的缓冲区r_bBufsc.read(r_bBuf);r_bBuf.flip();String msg = Charset.forName("UTF-8").decode(r_bBuf).toString();if(msg.equalsIgnoreCase("time")) {w_bBuf = ByteBuffer.wrap(getCurrentTime().getBytes("UTF-8"));sc.write(w_bBuf);w_bBuf.clear();} else if(msg.equalsIgnoreCase("bye")) {sc.write(ByteBuffer.wrap("已经与服务器断开连接".getBytes("UTF-8")));sc.socket().close();} else {sc.write(ByteBuffer.wrap(msg.getBytes("UTF-8")));}System.out.println(msg);System.out.println("处理完毕...");r_bBuf.clear();try {Thread.currentThread();Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}private String getCurrentTime() {Calendar date = Calendar.getInstance();String time = "服务器当前时间:" + date.get(Calendar.YEAR) + "-" + date.get(Calendar.MONTH)+1 + "-" + date.get(Calendar.DATE) + " " + date.get(Calendar.HOUR) + ":" + date.get(Calendar.MINUTE) + ":" + date.get(Calendar.SECOND);return time;}}
客户端代码实现:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;public class TestClient {public static void main(String[] args) {new MiniClient("localhost", 1982);}}class MiniClient {private SocketChannel sc;private ByteBuffer w_bBuf;private ByteBuffer r_bBuf = ByteBuffer.allocate(1024);public MiniClient(String host, int port) {try {InetSocketAddress remote = new InetSocketAddress(host, port);sc = SocketChannel.open();sc.connect(remote);if(sc.finishConnect()) {System.out.println("已经与服务器成功建立连接...");}while(true) {if(!sc.socket().isConnected()) {System.out.println("已经与服务器失去了连接...");return ;}BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String str = br.readLine();System.out.println("读入一行数据,开始发送...");w_bBuf = ByteBuffer.wrap(str.getBytes("UTF-8"));//将缓冲区中数据写入通道sc.write(w_bBuf);System.out.println("数据发送成功...");w_bBuf.clear();System.out.println("接收服务器端响应消息...");try {Thread.currentThread();Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}r_bBuf.clear();//将字节序列从此通道中读入给定的缓冲区r_bBufsc.read(r_bBuf);r_bBuf.flip();String msg = Charset.forName("UTF-8").decode(r_bBuf).toString();System.out.println(msg);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
- Java nio 实现socket异步通信 (对Java nio 实习笔记五中内容做一纠正)
- nio socket 异步通信 java
- 使用Java NIO实现异步的socket通信
- Java NIO(异步IO)Socket通信例子
- Java NIO Socket通信
- Java NIO Socket通信
- Java NIO Socket通信
- java NIO Socket通信
- Java NIO Socket通信
- java nio socket实现多线程多用户通信
- java NIO 实现非阻塞socket通信
- java nio 操作(2)异步阻塞 socket实现
- java nio学习之 socket+nio 通信
- java NIO socket 通信实例
- Java Socket编程(五)NIO
- Java Socket实战 使用NIO包实现Socket通信
- java nio 异步操作 (一)
- JAVA -NIO实现(一)
- IBM发布其分布式存储–XIV
- iOS平台上最给力的免费摄影应用
- Node.js 安装及npm的安装
- android CountDownTimer 倒数计时器
- CxImage下载
- Java nio 实现socket异步通信 (对Java nio 实习笔记五中内容做一纠正)
- VBScript 访问SQL数据库
- 458 - The Decoder
- Linux命令大全——umask命令
- Qt Event Dispatcher学习
- Android盈利模式,哪种更靠谱?
- Linux命令大全——ftp命令
- Linux命令使用大全——lsof用法
- C#中的String类