在上篇中,我们学习了 TCP Socket Server/Client 的简单读写,有了这些基础后,结合 Java 多线程编程,我们就可以轻松实现 Java 多线程处理客户端的通信,这里仅在上篇的分享中,做了小小的改动,加入多线程的处理,一起来看看具体实现吧。
Server
package org.example;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 单个server通过多线程处理多个客户端请求
*/
public class MultiThreadsSocketServer {
public static void main(String[] args) throws IOException {
System.out.println("------server------");
// 1.绑定端口,创建服务器
ServerSocket ss = new ServerSocket(8000);
boolean isRunning = true;
// 每新来一个客户端连接,创建新的线程处理请求
while (isRunning) {
// 2.等待客户端的连接
Socket so = ss.accept();
// 3.创建新的线程处理客户端请求
new Thread(new Channel(so)).start();
}
}
// 类内实现多线程接口
static class Channel implements Runnable {
private Socket so;
// input stream
private DataInputStream dis = null;
// output stream
private DataOutputStream dos = null;
// init
public Channel(Socket so) {
this.so = so;
try {
dis = new DataInputStream(so.getInputStream());
dos = new DataOutputStream(so.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
close();
}
}
// recv
private String receive() {
String content = "";
try {
content = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
// send
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// close
private void close() {
// dos -> dis -> so
try {
if (dos != null) {
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (dis != null) {
dis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (so != null) {
so.close();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.so.getRemoteSocketAddress().toString() + "'s resources have been released.");
}
// run, override
@Override
public void run() {
System.out.println("New a client conn...");
String username = "";
String pwd = "";
String[] datas = receive().split("&");
for (String info: datas) {
String[] userInfo = info.split("=");
if (userInfo[0].equals("username")) {
username = userInfo[1];
System.out.println("您的用户名:" + username);
} else if (userInfo[0].equals("pwd")) {
pwd = userInfo[1];
System.out.println("您的密码:" + pwd);
}
}
if (username.equals("abc") && pwd.equals("123456")) {
System.out.println("账号:" + username + ",登陆成功,欢迎回来。");
send("账号:" + username + ",登陆成功,欢迎回来。");
}else {
System.out.println("账号:" + username + ",登陆失败,请检测账号密码。");
send("账号:" + username + ",登陆失败,请检测账号密码。");
}
// release resources
close();
}
}
}
Client
package org.example;
import java.io.*;
import java.net.Socket;
public class MultiThreadsSocketClient {
public static void main(String[] args) throws Exception {
System.out.println("------client------");
// 1.建立连接
Socket client = new Socket("localhost", 8000);
// 2.IO操作
new Send(client).send();
new Recv(client).receive();
// 3.释放资源
client.close();
}
// send
static class Send {
private Socket client;
private DataOutputStream dos;
private BufferedReader br;
private String msg;
public Send(Socket client) {
br = new BufferedReader(new InputStreamReader(System.in));
this.msg = init();
this.client = client;
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
private String init() {
try {
System.out.println("请输入用户名:");
String username= br.readLine();
System.out.println("请输入密码:");
String pwd = br.readLine();
return "username=" + username + "&pwd=" + pwd;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void send() {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// recv
static class Recv {
private Socket client;
private DataInputStream dis;
public Recv(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void receive() {
String msg = null;
try {
msg = dis.readUTF();
System.out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
参考: