您的位置:首页 > 编程语言 > Java开发

Java 阻塞线程服务器

2014-01-21 10:41 375 查看
代码下载:http://pan.baidu.com/s/1ntEyLML

下面是一个阻塞线程服务器的代码例子。

EchoServer
package block;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

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 = ServerSocketChannel.open();
		// 使得在同一个主机上关闭了服务器程序,紧接着再启动该服务器程序时,可以顺利绑定相同的端口。
		serverSocketChannel.socket().setReuseAddress(true);
		// 把服务器进程与一个本地端口绑定
		serverSocketChannel.socket().bind(new InetSocketAddress(port));
		System.out.print("Service Start");
	}

	public void service() {
		while (true) {
			SocketChannel socketChannel = null;
			try {
				socketChannel = serverSocketChannel.accept();
				//处理客户连接
				 executorService.execute(new Handler(socketChannel));
				 
			} catch (IOException e) {
				// TODO: handle exception
				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;

		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			handle(socketChannel);
		}

		public void handle(SocketChannel socketChannel) {
			try {
				//获得与socketChannel关联的Socket对象
				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) {
				// TODO: handle exception
				e.printStackTrace();
			}finally{
				try {
					if (socketChannel != null) socketChannel.close();
				} catch (IOException e2) {
					// TODO: handle exception
					e2.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;
		}
		
	}

}


EchoServer类的构造方法负责创建线程池,启动服务器,把它绑定到一个本地端口。EchoServer类的service()方法负责接收客户的连接。每接收到一个客户连接,就把它交给线程来处理,线程池取出一个空闲的线程,来执行Handler对象的run()方法。Handler类的handler()方法负责与客户端通信。该方法先获得与SocketChannel关联的Socket对象,然后从Socket对象中得到输入流与输出流,再接收和发送数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: