java tcp socket 阻塞_Java Socket构建阻塞的TCP通信(4)

本文介绍了如何使用Java实现一个TCP Socket多线程服务器,通过ExecutorService线程池处理客户端连接请求。服务器在接收到客户端连接后,会创建一个Handler线程来处理该连接的读写操作,直至通信结束。文中还提到了Socket的关闭方法,包括完全关闭和半关闭输入、输出流的区别。
摘要由CSDN通过智能技术生成

InputStream socketIn = socket.getInputStream();

ByteArrayOutputStream buffer = new ByteArrayOutputStream();

byte[] buff = new byte[1024];

int len = -1;

while ((len = socketIn.read(buff)) != -1) {

buffer.write(buff, 0, len);

}

System.out.println(new String(buffer.toByteArray()));

(4)当调用Socket的close()方法关闭Socket时,它的输入流和输出流都被关闭。如果仅仅希望关闭输入或输出流其中之一,可调用半关闭方法:shutdownInput()和shutdownOutput()。先后调用Socket的shutdownInput()和shutdownOutput()方法,仅仅关闭输入流和输出流,并不等价于调用close()方法。在通信结束后仍然需要调用close()方法,因为该方法才会释放Socket占用的资源。

4.多线程服务器

EchoServer只能顺序的处理Client端的请求,这里使用ExecutorService指定一个线程池用于处理连接请求。

private ExecutorService executorService; // 线程池

private final int POOL_SIZE = 4; // 单个CPU时线程池中工作线程的数目

…….

executorService = Executors.newFixedThreadPool(Runtime.getRuntime()

.availableProcessors()* POOL_SIZE);

……

try {

socket = serverSocket.accept();

executorService.execute(new Handler(socket));

} catch (IOException e) {

e.printStackTrace();

}

Hander类封装了原来处理连接请求的逻辑,只要当前线程池中有空闲的线程,就可以用于处理请求。

源代码MultiEchoServer.java

public class MultiEchoServer {

private int port = 8000;

private ServerSocket serverSocket;

private ExecutorService executorService; // 线程池

private final int POOL_SIZE = 4; // 单个CPU时线程池中工作线程的数目

public MultiEchoServer() throws IOException {

serverSocket = new ServerSocket(port);

executorService = Executors.newFixedThreadPool(Runtime.getRuntime()

.availableProcessors()

* POOL_SIZE);

System.out.println("Server Start");

}

public void service() {

while (true) {

Socket socket = null;

try {

socket = serverSocket.accept();

executorService.execute(new Handler(socket));

} catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String args[]) throws IOException {

new MultiEchoServer().service();

}

}

class Handler implements Runnable {

private Socket socket;

public Handler(Socket socket) {

this.socket = socket;

}

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;

}

public void run() {

try {

System.out.println("New connection accepted "

+ 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 (socket != null)

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

参考 孙卫琴,《Java网络编程精解》

本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/124742

本文来源:子 孑博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值