java socket系列文章
java socket 单线程echo服务器
java socket 多线程echo服务器
java socket 线程池echo服务器
在文章java socket 单线程echo服务器中实现的echo服务器有一个问题,就是Server只能接受一个Client请求,当第一个Client连接后就占据了这个位置,后续Client不能再继续连接。在实际的网络环境里,同一时间只对一个用户服务是不可行的。一个优秀的网络服务程序除了能处理用户的输入信息,还必须能够同时响应多个客户端的连接请求。所以需要做些改动,当Server每接受到一个Client连接请求之后,都把处理流程放到一个独立的线程里去运行,然后等待下一个Client连接请求,这样就不会阻塞Server端接收请求了。每个独立运行的程序在使用完Socket对象之后要将其关闭。
客户端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class client {
public static void main(String[] args) throws IOException {
Socket client = new Socket("127.0.0.1", 20011);
//客户端请求与本机在20011端口建立TCP连接
client.setSoTimeout(10000);
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//获取键盘输入
PrintStream out = new PrintStream(client.getOutputStream());
//获取Socket的输出流,用来发送数据到服务端
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
//获取Socket的输入流,用来接收从服务端发送过来的数据
boolean flag = true;
while(flag){
System.out.print("输入信息:");
String str = input.readLine();
out.println(str);
//发送数据到服务端
if("bye".equals(str)){
flag = false;
}else{
try{
//从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常
String echo = buf.readLine();
System.out.println(echo);
}catch(SocketTimeoutException e){
System.out.println("Time out, No response");
}
}
}
input.close();
if(client != null){
//如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭
client.close(); //只关闭socket,其关联的输入输出流也会被关闭
}
}
}
服务器端代码
public class MultiThreadServer{
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(20012);
Socket client = null;
while(true){
System.out.println("服务器端等待客户端发起连接请求");
client = server.accept();
System.out.println("客户端向服务器端发起了连接请求,且连接成功");
new Handler(client);
}
}
}
这个程序监听20012端口,并将接受到的客户端请求交给Handler线程运行。Handler线程接受客户端的输入,并将输入返回给客户端,直到客户端输入”bye”,线程结束。
线程处理代码
public class Handler extends Thread{
private Socket client;
PrintStream out;
BufferedReader buf;
public Handler(Socket client){
this.client = client;
try {
out = new PrintStream(client.getOutputStream());
buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
start();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
try{
boolean flag =true;
while(flag){
String str = buf.readLine();
if(str == null || "".equals(str)){
flag = false;
}else{
if("bye".equals(str)){
flag = false;
}else{
System.out.println("服务器从客户端接受到的数据:"+str);
out.println("echo:" + str);
}
}
}
out.close();
buf.close();
client.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
首先运行MultiThreadServer类,然后运行两个Client类,然后分别在每个MyClient的提示符下输入字符串,就可以看到MultiThreadServer
可以分别接收处理每个Client的请求了。
此项目的完整代码可以到我的github,java-socket进行下载。