在ServerSocket和Socket的模拟中,假定服务器需要处理多个实时客户端的连接,那么需要用到多线程进行解决这个问题,我们只需要将对socket的操作放在线程中即可。
在ServerSocket中客户端的每次连接,我们都使用accept来获取socket,之后将socket传给线程,在线程中实现对socket的具体操作,不管是获取数据还是回传数据。
1、新建ServerThread类
在ServerThread中需要对socket进行操作,这个socket是在ServerSocket的accept方法获取的,因此根据合成复用原则,在线程类中创建成员变量socket,利用构造方法将外部的socket赋值给成员变量,之后进行操作。
public class ServerThread extends Thread {
// 合成复用原则
private Socket s;
public ServerThread(Socket s){
this.s = s;
}
@Override
public void run() {
BufferedReader br = null;
PrintStream ps = null;
try {
// 3.使用输入输出流进行通信
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
ps = new PrintStream(s.getOutputStream());
while(true){
// 接受客户端传的数据
String str = br.readLine();
// 如果传来的数据是bye,那么通信结束
System.out.println("客户端传的值是:" + str);
if("bye".equalsIgnoreCase(str)){
System.out.println("客户端"+ s.getInetAddress() +"结束通信!");
break;
}
// 从服务器回传客户端的值
ps.println("I get it.");
System.out.println("服务器发送数据成功!");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// 4.关闭Socket并释放资源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != ps) {
ps.close();
}
if (null != s) {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2、优化ServerSocket类
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
try {
// 1.新建ServerSocket,指定监听端口号
ss = new ServerSocket(5555);
// 2.等待客户端的连接请求,调用accept方法
while(true){
System.out.println("服务端正在等待连接...");
s = ss.accept();
System.out.println("客户端"+s.getInetAddress()+"连接成功...");
<!----------------此处开启新的线程------------------->
// 每次有一个新的客户端连接,那么启动一个新的线程进行连接
new ServerThread(s).start();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// 4.关闭Socket并释放有关的资源
if(null != ss){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、结果展示
结束-----------------------------------------------------------------------------------------------------------