Socket|Socket 实现(一对多)聊天室(多线程)代码+注释
1.使用server.accept()实现链接,开线程处理socket实例处理信息交互。
2.控制输出同时使用线程接收服务端返回的信息,
ps:
Server服务端代码如下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
/**
* 服务端
* 处理多个client连接任务
* @author natcheng
*
*/
public class Server {
private ServerSocket server;
//所有的客户端信息流
private Collection【Socket|Socket 实现(一对多)聊天室(多线程)代码+注释】 allpw = new ArrayList();
/**
* 构造:初始成员变量
*/
public Server() {
try {
System.out.println("Server is starting...");
server = new ServerSocket(8088);
System.out.println("Server is ready!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 服务端启动连接客户端并处理信息交互
*/
public void start() {
try {
//accept()方法对接客户端形成socket实例
System.out.println("Ready for client...");
Socket socket = server.accept();
System.out.println("Connection succeeded!");
//开线程接client
Runnable r1 = new ClientHandler(socket);
Thread t1 = new Thread(r1);
t1.start();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 内部类,实现开线程接待Client中的Socket实例信息交互
* @author soft01
*
*/
private class ClientHandler implements Runnable{
private Socket socket;
private String host;
/**
* 内部类构造,接accept()返回的socket
* @param socket
*/
public ClientHandler(Socket socket) {
this.socket = socket;
InetAddress it = socket.getInetAddress();
this.host = it.getHostAddress();
}
/**
* 线程方法run
*/
PrintWriter pw;
public void run() {
Thread t = Thread.currentThread();
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream(),"UTF-8"));
pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream(),"UTF-8")),true);
synchronized(allpw) {
allpw.add(pw);
System.out.println("同时在线人数:"+allpw.size());
}
String clientMsg = null;
while(t.isAlive()) {
if((clientMsg=br.readLine())!= null) {
System.out.println(clientMsg);
}
//同时返回给各个客户端这条信息:
synchronized(allpw) {
for(PrintWriter everyPw:allpw) {
everyPw.println(host+"说:"+clientMsg);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//下线踢除pw
if(t.isInterrupted()) {
synchronized(allpw) {
allpw.remove(pw);
}
System.out.println(host+",offline!");
//socket关闭
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
Client 客户端代码如下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 客户端
* @author soft01
*
*/
public class Client {
private Socket socket;
/**
* 构造:初始化socket,连接服务端
*/
public Client() {
try {
System.out.println("Client is starting...");
this.socket=new Socket("localhost",8088);
System.out.println("Client start successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 启动信息交互
*/
public void start() {
//发送信息(开线程)
Runnable r = new OutputMsg();
Thread t = new Thread(r);
t.start();
//接收信息
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream(),"UTF-8"));
String serverMsg = null;
while((serverMsg=br.readLine())!= null) {
System.out.println(serverMsg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class OutputMsg implements Runnable{
public void run() {
try {
PrintWriter pw = new PrintWriter(
new BufferedWriter (
new OutputStreamWriter(socket.getOutputStream(),"UTF-8")),true);
System.out.println("input msg:");
Scanner scan = new Scanner(System.in);
String inputMsg = scan.nextLine();
pw.println(inputMsg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 主方法
* @param args
*/
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM