同步阻塞式IO(BIO)--学习笔记
2016-05-25 16:06
411 查看
线程模型如下:
采用BIO模式的socket服务端,通常由独立的Acceptor线程负责监听客户端连接,如果没有客户端发送连接,Accpetor 会一直处于阻塞状态。在接收到客户端请求后,创建一个线程来处理该请求,处理完成后可以通过输出流回应客户端,然后线程销毁。线程和客户端并发数相等。完全是一次请求一次应答模式。
如果你有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的BIO服务器实现可能非常契合。对于高并发访问,每次访问创建一个新的线程处理显然不可行。
以下是javaSocket 实现代码:
服务器端全部测试代码:
package bioFrame.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import bioFrame.server.handler.StringServerHandler;
/**
* 同步阻塞式IO,为每个链接创建一个线程
*
* @author Mercy
*
*/
public class ServerMain {
public static int port = 9001;//默认监听端口
public static void main(String[] args){
System.out.println("Server start……");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
while(true){
Socket socket = serverSocket.accept();
new Thread(new StringServerHandler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
StringServerHandler 用来解析收到的文本内容
package bioFrame.server.handler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* 用于接收客户端发来的文本消息,输出到控制台,并返回给客户端一个时间戳
* @author Mercy
*
*/
public class StringServerHandler implements Runnable{
private Socket socket;
public StringServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuffer sb = new StringBuffer();
while(br.ready()){//判断是否已准备好被读取
sb.append(br.readLine());
}
// String content = br.readLine();
// while(content != null){
// sb.append(content);
// content = br.readLine();//这里会阻塞?
// }
System.out.println("Server recive :" + sb.toString());
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.print(String.valueOf(System.currentTimeMillis()));
pw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
br = null;
}
if(socket != null){
if(!socket.isClosed()){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
}
socket客户端测试代码如下:
package bioFrame.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* 同步阻塞式IO,发送文本内容给服务器,读取服务器响应,并打印结果
* @author Mercy
*
*/
public class ClientMain {
/**
* 要连接的服务器端口
*/
private static int port = 9001;
private static String ip = "127.0.0.1";
public static void main(String[] args){
Socket socket = null;
try {
socket = new Socket(ip,port);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println("这里是第一行内容");
pw.println("这里是第二行内容");
pw.flush();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("client recive :" + bufferedReader.readLine());
pw.close();
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(socket != null){
if(!socket.isClosed()){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
}
采用BIO模式的socket服务端,通常由独立的Acceptor线程负责监听客户端连接,如果没有客户端发送连接,Accpetor 会一直处于阻塞状态。在接收到客户端请求后,创建一个线程来处理该请求,处理完成后可以通过输出流回应客户端,然后线程销毁。线程和客户端并发数相等。完全是一次请求一次应答模式。
如果你有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的BIO服务器实现可能非常契合。对于高并发访问,每次访问创建一个新的线程处理显然不可行。
以下是javaSocket 实现代码:
服务器端全部测试代码:
package bioFrame.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import bioFrame.server.handler.StringServerHandler;
/**
* 同步阻塞式IO,为每个链接创建一个线程
*
* @author Mercy
*
*/
public class ServerMain {
public static int port = 9001;//默认监听端口
public static void main(String[] args){
System.out.println("Server start……");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
while(true){
Socket socket = serverSocket.accept();
new Thread(new StringServerHandler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
StringServerHandler 用来解析收到的文本内容
package bioFrame.server.handler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* 用于接收客户端发来的文本消息,输出到控制台,并返回给客户端一个时间戳
* @author Mercy
*
*/
public class StringServerHandler implements Runnable{
private Socket socket;
public StringServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuffer sb = new StringBuffer();
while(br.ready()){//判断是否已准备好被读取
sb.append(br.readLine());
}
// String content = br.readLine();
// while(content != null){
// sb.append(content);
// content = br.readLine();//这里会阻塞?
// }
System.out.println("Server recive :" + sb.toString());
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.print(String.valueOf(System.currentTimeMillis()));
pw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
br = null;
}
if(socket != null){
if(!socket.isClosed()){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
}
socket客户端测试代码如下:
package bioFrame.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* 同步阻塞式IO,发送文本内容给服务器,读取服务器响应,并打印结果
* @author Mercy
*
*/
public class ClientMain {
/**
* 要连接的服务器端口
*/
private static int port = 9001;
private static String ip = "127.0.0.1";
public static void main(String[] args){
Socket socket = null;
try {
socket = new Socket(ip,port);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println("这里是第一行内容");
pw.println("这里是第二行内容");
pw.flush();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("client recive :" + bufferedReader.readLine());
pw.close();
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(socket != null){
if(!socket.isClosed()){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
}
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- java socket 注意的地方
- java socket 注意的地方
- C#基于socket模拟http请求的方法
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- 使用C#来编写一个异步的Socket服务器
- C#使用Socket快速判断数据库连接是否正常的方法
- 科学知识:理解socket
- 探究在C++程序并发时保护共享数据的问题
- Android聊天工具基于socket实现
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket
- 在ASP.NET 2.0中操作数据之四十八:对SqlDataSource控件使用开放式并发
- 在ASP.NET 2.0中操作数据之二十一:实现开放式并发
- C#使用Socket上传并保存图片的方法
- 深入php socket的讲解与实例分析
- Nodejs实战心得之eventproxy模块控制并发