JAVA网络编程(一):阻塞IO实现
来源:互联网 发布:淘宝软件代理商加盟 编辑:程序博客网 时间:2024/06/04 18:00
最近想彻底弄明白Java网络编程,就结合一些资料自己捣鼓了下。
先从BIO说起吧。
BIO就是Blocking IO,通过acceptor监听客户端的连接,来一个客户端就新建一个线程处理,完成处理之后通过输出流应答客户端,最后销毁线程。多说无益,上图(太cho)丑,凑合看)
服务端类:
public class BlockTimeServer { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8080); Socket socket = null; while (true) { System.out.println("等待连接"); socket = serverSocket.accept();//这个方法会一直阻塞至有客户端连接 new Thread(new BlockTimeServerHandler(socket)).start();//启动线程处理,主线程会继续阻塞等待下一个客户端连接 System.out.println("已连接"); } } catch (IOException e1) { e1.printStackTrace(); if (serverSocket != null) { try { serverSocket.close(); serverSocket = null; } catch (IOException e) { e.printStackTrace(); } } } finally { } }}服务端处理的句柄:
public class BlockTimeServerHandler implements Runnable { private Socket socket; public BlockTimeServerHandler(Socket socket) { this.socket = socket; } @Override public void run() { System.out.println("启动线程"); BufferedReader reader = null; PrintWriter writer = null; try { reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); writer = new PrintWriter(socket.getOutputStream(), true); while (true) { String request = reader.readLine();//之前一直阻塞,矮凳子绊倒人,忘了行要结尾 if (request == null) { break; } System.out.println("get order:" + request);//接收端用到的是readLine方法,这里必须是println,否则会一直阻塞 String response = "getTime".equals(request) ? new Date().toString() : "bad order"; System.out.println("response time :"+response); writer.println(response); } } catch (IOException e1) { e1.printStackTrace(); if (reader != null) { try { reader.close(); reader = null; } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { writer.close(); writer = null; } if (socket != null) { try { socket.close(); socket = null; } catch (IOException e) { e.printStackTrace(); } } } }}
客户端代码:
public class BlockTimeClient { public static void main(String[] args) { Socket socket = null; BufferedReader reader = null; BufferedReader in = null; PrintWriter out = null; try { socket = new Socket("localhost", 8080); System.out.println("请输入指令"); reader = new BufferedReader(new InputStreamReader(System.in)); String order = reader.readLine(); System.out.println("发送指令:"+order); out = new PrintWriter(socket.getOutputStream(),true); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.println(order); System.out.println("发送成功"); String resp = in.readLine(); System.out.print("收到返回:"); System.out.println(resp); socket.close(); } catch (IOException e1) { e1.printStackTrace(); } finally { if (socket != null) { try { socket.close(); socket = null; } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); reader = null; } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); in = null; } catch (IOException e) { e.printStackTrace(); } } if (out != null) { out.close(); out = null; } } }}
这种方法中,每个连接过来服务端都会创建一个线程处理,而线程是系统的稀缺资源,如果每个请求都要新建线程,将可能导致服务器资源耗尽,因此明显这种实现方式是不能处理海量请求的,有一个解决方案是使用线程池。线程池是启动前已经初始化好的,不论后来的请求怎么增加,线程数始终都在线程池的最大数量之中,因此不会出现服务器资源耗尽的情况,这种方式被称为伪异步方式。上代码(只需要改动acceptor就可以):
public class BlockTimeWithPoolServer { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; try { serverSocket = new ServerSocket(8080); Executor executor = Executors.newFixedThreadPool(100); while (true) { socket = serverSocket.accept(); executor.execute(new BlockTimeServerHandler(socket)); } } catch (IOException e) { e.printStackTrace(); } }}
文件参考:《netty权威指南》
0 0
- JAVA网络编程(一):阻塞IO实现
- Java网络编程 - 同步阻塞IO模型
- java网络编程(一):java传统的阻塞IO以及多线程解决方案
- 网络编程--IO模型示例(阻塞式IO)
- java网络编程(三)--非阻塞IO(通道、缓冲区、选择器)
- Linux网络编程(三) IO非阻塞操作
- Linux网络编程(三) IO非阻塞操作 .
- 深入linux网络编程(二):异步阻塞IO
- unix网络编程(五)--IO复用+非阻塞
- UNIX网络编程笔记(12)—非阻塞IO
- java中网络编程之socket编程(一)--Tcp同步阻塞式
- Unix网络编程学习日记(一):半双工非阻塞socket客户端的实现
- 阻塞与非阻塞IO -- 网络编程随想
- 网络编程----阻塞、非阻塞和同步、异步IO
- 网络编程io总结区分。阻塞,非阻塞,异步,同步
- 网络编程Socket的阻塞和非阻塞IO
- java网络编程之传统IO与伪异步IO(一)
- 翻译:使用Libevent的快速可移植非阻塞网络编程:异步IO简介 (一)
- PATH,CLASSPATH都配置好情况下,javac编译java文件后,生成class文件,再用java去运行,出现错误:找不到或无法加载主类。
- Android开发之onTouch事件的分发拦截消费机制探究学习
- 初学者用jQuery ajax 添加表单数据 ssm项目 报415错误
- iOS屏幕适配
- 同时上内网和外网
- JAVA网络编程(一):阻塞IO实现
- uva 11440 Help Mr. Tomisu 欧拉函数变种
- 数字到字符串转换问题
- Codeforces 371C - Sonya and Queries(思维)
- PRML读书笔记(1)——introduction
- iOS内存管理之NSAutoreleasePool
- 让人深思的退役贴
- Android中各种context的使用范围
- POJ 1637 Sightseeing tour 混合图的欧拉回路