EchoServer.java (阻塞模式)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EchoServer.java (阻塞模式)相关的知识,希望对你有一定的参考价值。
package block;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
public class EchoServer {
private int port=8000;
private ServerSocketChannel serverSocketChannel = null;
private ExecutorService executorService;
private static final int POOL_MULTIPLE = 4;
public EchoServer() throws IOException {
executorService= Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors() * POOL_MULTIPLE);
serverSocketChannel= ServerSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
System.out.println("服务器启动");
}
public void service() {
while (true) {
SocketChannel socketChannel=null;
try {
socketChannel = serverSocketChannel.accept();
executorService.execute(new Handler(socketChannel));
}catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[])throws IOException {
new EchoServer().service();
}
}
class Handler implements Runnable{
private SocketChannel socketChannel;
public Handler(SocketChannel socketChannel){
this.socketChannel=socketChannel;
}
public void run(){
handle(socketChannel);
}
public void handle(SocketChannel socketChannel){
try {
Socket socket=socketChannel.socket();
System.out.println("接收到客户连接,来自: " +
socket.getInetAddress() + ":" +socket.getPort());
BufferedReader br =getReader(socket);
PrintWriter pw = getWriter(socket);
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
pw.println(echo(msg));
if (msg.equals("bye"))
break;
}
}catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(socketChannel!=null)socketChannel.close();
}catch (IOException e) {e.printStackTrace();}
}
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public String echo(String msg) {
return "echo:" + msg;
}
}
/****************************************************
* 作者:孙卫琴 *
* 来源:<<Java网络编程精解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
public class EchoServer {
private int port=8000;
private ServerSocketChannel serverSocketChannel = null;
private ExecutorService executorService;
private static final int POOL_MULTIPLE = 4;
public EchoServer() throws IOException {
executorService= Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors() * POOL_MULTIPLE);
serverSocketChannel= ServerSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
System.out.println("服务器启动");
}
public void service() {
while (true) {
SocketChannel socketChannel=null;
try {
socketChannel = serverSocketChannel.accept();
executorService.execute(new Handler(socketChannel));
}catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[])throws IOException {
new EchoServer().service();
}
}
class Handler implements Runnable{
private SocketChannel socketChannel;
public Handler(SocketChannel socketChannel){
this.socketChannel=socketChannel;
}
public void run(){
handle(socketChannel);
}
public void handle(SocketChannel socketChannel){
try {
Socket socket=socketChannel.socket();
System.out.println("接收到客户连接,来自: " +
socket.getInetAddress() + ":" +socket.getPort());
BufferedReader br =getReader(socket);
PrintWriter pw = getWriter(socket);
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
pw.println(echo(msg));
if (msg.equals("bye"))
break;
}
}catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(socketChannel!=null)socketChannel.close();
}catch (IOException e) {e.printStackTrace();}
}
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public String echo(String msg) {
return "echo:" + msg;
}
}
/****************************************************
* 作者:孙卫琴 *
* 来源:<<Java网络编程精解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
EchoServer 类的构造负责创建线程池,启动服务器,把它绑定到一个本地端口。EchoServer类的service()方法负责接收客户的连接。每接收一个客户连接,就把它交给线程池来处理,线程池取出一个空闲的线程,来执行Handler对象的run()方法。Handler类的handle()负责与客户通信。该方法先获得与SocketChannel关联的Socket对象,然后从Socket对象中得到输入流与输出流,再接收和发送数据。
SocketChanle实际上也是提供了read(ByteBuffer buffer),但是通过它来读取一行字符比较麻烦。一下radLine()方法就通过SocketChannel的read(ByteBuffer buffer)方法来读取一行字符串。它的作用与BufferReader的readLine()方法等价的。
SocketChanle实际上也是提供了read(ByteBuffer buffer),但是通过它来读取一行字符比较麻烦。一下radLine()方法就通过SocketChannel的read(ByteBuffer buffer)方法来读取一行字符串。它的作用与BufferReader的readLine()方法等价的。
//*******************
public String readLine(SocketChannel socketChannel)throws IOException{
ByteBuffer buffer = ByteBuffer.allocate(1024);
ByteBuffer tempBuffer =ByteBuffer.allocate(1);
boolean isLine = false;
boolean isEnd = false;
String data = null;
while(!isLine && !isEnd){
tempBuffer.clear();
int n = socketChannel.read(tempBuffer);
if(n==-1){
isEnd = true;
break;
}
if(n==0) continue;
tempBuffer.flip();
buffer.put(tempBuffer);
buffer.flip();
Charset charset = Charset.forName("GBK");
CharBuffer charBuffer = charset.decode(buffer);
data = charBuffer.toString();
if(data.indexOf("\r\n")!=-1){
isLine = true;
data = data.substring(0,data.indexOf("\r\n"));
break;
}
buffer.position(buffer.limit());
buffer.limit(buffer.capacity());
}
return data;
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
ByteBuffer tempBuffer =ByteBuffer.allocate(1);
boolean isLine = false;
boolean isEnd = false;
String data = null;
while(!isLine && !isEnd){
tempBuffer.clear();
int n = socketChannel.read(tempBuffer);
if(n==-1){
isEnd = true;
break;
}
if(n==0) continue;
tempBuffer.flip();
buffer.put(tempBuffer);
buffer.flip();
Charset charset = Charset.forName("GBK");
CharBuffer charBuffer = charset.decode(buffer);
data = charBuffer.toString();
if(data.indexOf("\r\n")!=-1){
isLine = true;
data = data.substring(0,data.indexOf("\r\n"));
break;
}
buffer.position(buffer.limit());
buffer.limit(buffer.capacity());
}
return data;
}
以上是关于EchoServer.java (阻塞模式)的主要内容,如果未能解决你的问题,请参考以下文章