要求
实现多用户访问,要求实现服务器与客户端代码。
提示:服务器端需要多线程响应客户端请求。
分析
- 为满足多用户访问,我们将服务端放在一个while循环。
- 等待用户连接,只要有客户端接入就马上创建一个线程并启动。
效果图
代码实现
服务端
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8888);
/*
* 通过循环不断等待客户端连接,只要一出现连接就创建一个新的线程并马上启动
*/
while(true) {
Socket client = server.accept();
Thread thread = new Thread(new MyThreadServer(client));
thread.start();
}
}
}
服务器端代码相对简单,因为每次连接都要启动一个新的线程,所以在这里我自己定义了一个实现了Runnable接口的MyThreadServer类。
public class MyThreadServer implements Runnable{
private Socket client;
public MyThreadServer(Socket client) {
this.client = client;
}
@Override
public void run() {
boolean flag = true;
PrintStream output = null; //往外输出
Scanner input= null; // 获取客户端输出值做服务器输入值
try {
String str = "";
output = new PrintStream(this.client.getOutputStream());
input = new Scanner(this.client.getInputStream()).useDelimiter("\n");
while(flag) {
if(input.hasNext()) {
str = input.next().trim();
if(str.contains("我是谁")) {
output.println("【服务器】:你是"+this.client.toString());
}
else if("byebye".equalsIgnoreCase(str)) {
System.out.println("已断开连接");
flag = false;
}
else {
output.println(str);
System.out.println("来自"+str);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
input.close();
output.close();
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
客户端我一样采用了继承Thread的方法(现在看来这个操作更像是多此一举~)。
public class Client extends Thread{
private String name;
private Socket socket;
public static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));
public static String getString(String str) throws Exception {
System.out.print(str);
return KEYBOARD_INPUT.readLine();
}
public Client(String name) {
try {
this.socket = new Socket("127.0.0.1", 8888);
}catch (Exception e) {
e.printStackTrace();
}
this.name = name;
}
@Override
public void run() {
try{
Scanner read = new Scanner(this.socket.getInputStream()).useDelimiter("\n");
PrintStream output = new PrintStream(this.socket.getOutputStream());
while(true) {
String result = getString("请输入要发送的内容:");
if("byebye".equals(result)) {
output.println(result);
break;
}
output.println(this.name+":"+result);
if(read.hasNext()) {
System.out.println("[服务器]:"+read.next());
}
}
read.close();
output.close();
this.socket.close();
}catch(Exception e) {
e.printStackTrace();
}
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
现在如果我们要创建一个新的客户端对象连接服务端,只需要创建一个Client线程并启动即可。