TCP的实现(二)
在(一)中只用了一个线程来处理客户端连接,显然这样是不合适的,客户端只能一个一个的去连接服务器。
现在原来的程序,每次获取到一个客户端连接之后,启动一个线程去处理它,服务器主线程继续等待客户端的其他连接。怎么做呢?只要在获取到客户端的连接之后,启动新线程就可以了。
这个服务器还是只有一个功能,只是把客户端获取的数据,直接写回去。
package mxf.study.java.nio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.MessageFormat;
public class TCPMultiThreadServer {
public static void main(String[] args) throws IOException{
startServer(10000);
}
private static void startServer(int port) throws IOException{
ServerSocket servSocket = new ServerSocket(port);
System.out.println(MessageFormat.format("开始启动监听,端口号:{0}", 10000));
// 循环迭代,监听端口号,处理新的连接请求
int i = 0;
while (true) {
// 阻塞等待,每接收到一个请求就创建一个新的连接实例
Socket clntSocket = servSocket.accept();
new Thread(new ServerThread(clntSocket), "线程" + (i++)).start();
}
}
}
class ServerThread implements Runnable{
private static final int BUFSIZE = 32;
Socket clntSocket;
// 接收数据的缓冲区
byte[] receiveBuf = new byte[BUFSIZE];
public ServerThread(Socket clntSocket) {
super();
this.clntSocket = clntSocket;
}
@Override
public void run() {
try {
// 从客户端接收数据的对象
InputStream in = clntSocket.getInputStream();
// 向客户端发送数据的对象
OutputStream out = clntSocket.getOutputStream();
// 初始接收数据的总字节数
int recvMsgSize;
// 读取客户端发送的数据后,再发送到客户端
while ((recvMsgSize = in.read(receiveBuf)) != -1) {
out.write(receiveBuf, 0, recvMsgSize);
System.out.println("服务器 线程" + Thread.currentThread().getName() + "Received:" + new String(receiveBuf));
}
out.flush();
// 客户端关闭连接时,关闭连接
System.out.println(" 客户端关闭连接");
clntSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在NIO之前,基本上服务器都是这么写的,但是这有很多问题,比如,怎么控制线程数量啊?(线程池或许是比较好)频繁创建线程也不是好事情。下一篇先把线程池整出来。
浙公网安备 33010602011771号