NIO入门之BIO
传统BIO编程
网络编程的基本模型是Client-Server模型,也就是两个进程之间相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的端口发起连接请求,通过三次握手建立连接,如果连接成功,双方就可以通过网络套接字(Socket)进行通信。
在传统的BIO编程中,ServerSocket负责绑定IP地址,启动端口监听,Socket负责发起连接请求,连接成功之后,双方通过输入和输出流进行同步阻塞通信。
下面通过TimeServer的一个例子,回顾和熟悉BIO编程
BIO通信模型图
可以看到再改模型中,有一个Acceptor线程负责监听客户端的连接,并为每个请求创建一个新的线程进行处理。
我们可以发现该模型最大问题就是缺乏弹性伸缩能力,服务端和客户端线程个数是1比1的关系。
BIO的TimeServer
package nio.bio;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by jj on 2018/12/23.
*/
public class TimeServer {
public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length >0){
try{
port = Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
ServerSocket server = null;
try{
server = new ServerSocket(port);
Socket socket = null;
while (true){
socket = server.accept();
new Thread(new TimeServerHandler(socket)).start();
}
}finally {
if (server!= null){
server.close();
server = null;
}
}
}
}
如果没有客户端请求,则阻塞在server.accept操作上,如果有,则创建一个TimeServerHandler的Runnable线程,处理客户端的Socket链路
下面,我们看一下TimeServerHandler
public class TimeServerHandler implements Runnable{
private Socket socket;
public TimeServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try{
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
out = new PrintWriter(this.socket.getOutputStream(),true);
String curentTime = null;
String body = null;
while (true){
body = in.readLine();
if (body == null)
break;
System.out.println("the time server receive order:" + body);
curentTime = "QUERY TIME ORDER".equalsIgnoreCase(body)?new Date(
System.currentTimeMillis()
).toString():"BAD ORDER";
out.println(curentTime);
}
} catch (Exception e) {
if (in != null){
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (out != null){
out.close();
out = null;
}
if (this.socket !=null){
try {
this.socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
this.socket = null;
}
}
}
}
可以看到run中的功能为读取客户端请求,并通过PrintWriter返回给客户端相应。
下面我们看一下客户端的代码
public class TimeClient {
public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
}
}
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
try{
socket = new Socket("127.0.0.1",port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
out.println("QUERY TIME ORDER");
String resp = in.readLine();
System.out.print(resp);
}finally {
if (out != null){
out.close();
out = null;
}
if (in != null){
in.close();
in = null;
}
if (socket != null){
socket.close();
socket = null;
}
}
}
}
NIO入门之BIO的更多相关文章
- 第二章 NIO入门
传统的同步阻塞式I/O编程 基于NIO的非阻塞编程 基于NIO2.0的异步非阻塞(AIO)编程 为什么要使用NIO编程 为什么选择Netty 第二章 NIO 入门 2.1 传统的BIO编程 2.1.1 ...
- Java NIO入门(二):缓冲区内部细节
Java NIO 入门(二)缓冲区内部细节 概述 本文将介绍 NIO 中两个重要的缓冲区组件:状态变量和访问方法 (accessor). 状态变量是前一文中提到的"内部统计机制"的 ...
- Java NIO入门
NIO入门 前段时间在公司里处理一些大的数据,并对其进行分词.提取关键字等.虽说任务基本完成了(效果也不是特别好),对于Java还没入门的我来说前前后后花了2周的时间,我自己也是醉了.当然也有涉及到机 ...
- NIO入门之轻松读取大文件
NIO入门之轻松读取大文件 今天同事碰到了一个问题,从游戏服务器下载下来的输出log有一个多G大.用记事本打不开,EditPlus也打不开,都提示文件太大.用word也打不开,提示文件大于512M.打 ...
- NIO 入门(转)
NIO 入门 Greg Travis2003 年 11 月 17 日发布 分享此页面 WeiboGoogle+用电子邮件发送本页面 20 在开始之前 关于本教程 新的输入/输出 (NIO) 库是在 J ...
- NIO入门-----01
package com.sico.pck01_nio; import java.nio.ByteBuffer; import org.junit.Test; /** * @author Sico ...
- 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!
本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...
- 从Socket入门到BIO,NIO,multiplexing,AIO
Socket入门 最简单的Server端读取Client端内容的demo public class Server { public static void main(String [] args) t ...
- 从Socket入门到BIO,PIO,NIO,multiplexing,AIO(未完待续)
Socket入门 最简单的Server端读取Client端内容的demo public class Server { public static void main(String [] args) t ...
随机推荐
- Opencv3.3.1安装包
这个资源是Opencv3.3.1安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载
- 201621123034 《Java程序设计》第9周学习总结
作业09-集合与泛型 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 答:Map的HashMap中使用嵌套类static class Node<K,V& ...
- 前端构建工具gulpjs的使用介绍及技巧 (转)
gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...
- BZOJ 1731: [Usaco2005 dec]Layout 排队布局
Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ ...
- BZOJ4894 天赋 【矩阵树定理】
题目链接 BZOJ4894 题解 双倍经验P5297 题解 #include<iostream> #include<cstring> #include<cstdio> ...
- bestcoder15_love
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> ...
- 使用 redux 监听插件的使用
首先需要在chrome浏览器当中下载redux插件 接着在你的项目当中加上**window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX ...
- 封装scroll()
function scroll(){ if(window.pageYOffset !== undefined){ return { "top": window.pageYOffse ...
- BAT脚本编写教程入门提高篇
BAT脚本编写教程入门提高篇 批处理文件的参数 批处理文件还可以像C语言的函数一样使用参数(相当于DOS命令的命令行参数),这需要用到一个参数表示符“%”. %[1-9]表示参数,参数是指在运行批处理 ...
- Unicode字符集和多字节字符集关系
在计算机中字符通常并不是保存为图像,每个字符都是使用一个编码来表示的,而每个字符究竟使用哪个编码代表,要取决于使用哪个字符集(charset). 在最初的时候,Internet上只有一种字符集—— ...