上一篇文章是点对点的聊天,没有多线程,而这个就用多线程实现了群聊,只是个简易版哈哈
package com.softeem.streamdemo52;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 服务器
*
*/
public class Server extends Thread{
//声明一个容器用于存储所有的Socket对象
static List<Socket> list = new ArrayList<>();
private Socket s;
public Server(Socket s) {
this.s = s;
}
@Override
public void run() {
//接收其中一个客户端发送过来的消息并转发给所有的客户端
new ChatServer(s).start();
}
public static void main(String[] args) throws IOException {
//占据指定端口创建服务
ServerSocket ss = new ServerSocket(8888);
System.out.println("服务器启动。。。");
while(true){
Socket s = ss.accept();
list.add(s);
Tools.msg("客户连接成功:"+Tools.showIp(s.getInetAddress()));
new Server(s).start();
}
}
}
package com.softeem.streamdemo52;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.text.DateFormat;
import java.util.Date;
/**
* 工具类
*
*/
public class Tools {
/**
* 消息输出
* @param msg
*/
public static void msg(Object msg){
System.out.println(msg);
}
/**
* ip输出
* @param ip
* @return
*/
public static String showIp(InetAddress ip){
return ip.getHostAddress();
}
/**
* 封装字节转字符并包装成缓冲流
*/
public static BufferedReader getBuffer(InputStream is){
return new BufferedReader(new InputStreamReader(is));
}
/**
* 发送消息
* @throws IOException
*/
public static void sendMsg(Socket s,Socket sitem,String msg) throws IOException{
PrintWriter pw = new PrintWriter(sitem.getOutputStream());
pw.println(msgFmt(s,msg));
pw.flush();
}
/**
* 不包含格式的发送消息
* @throws IOException
*/
public static void sendMsg2(Socket s,String msg) throws IOException{
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println(msg);
pw.flush();
}
/**
* 格式化显示消息内容 192.168.4.254【16:22:32】:hello
*/
public static String msgFmt(Socket s,String msg){
return showIp(s.getInetAddress())+"【"+fmtSysTime()+"】:"+msg;
}
/**
* 格式化系统时间
* @return
*/
public static String fmtSysTime(){
return DateFormat.getDateTimeInstance().format(new Date());
}
}
package com.softeem.streamdemo52;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;
![](/qrcode.jpg)
public class ChatServer extends Thread{
private Socket s;
public ChatServer(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
BufferedReader br = Tools.getBuffer(s.getInputStream());
String msg = "";
while((msg=br.readLine())!=null){
for (Socket sitem : Server.list) {
Tools.sendMsg(s, sitem, msg);
}
}
} catch(SocketException e){
//客户端退出,并输出客户端的ip地址
System.err.println("客户端退出:"+Tools.showIp(s.getInetAddress()));
Server.list.remove(s);
}catch (IOException e) {
e.printStackTrace();
}
}
}
package com.softeem.streamdemo52;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.Socket;
/**
* @author 李磊
*
*/
public class MsgReceiver extends Thread{
private Socket s;
public MsgReceiver(Socket s){
super();
this.s = s;
}
@Override
public void run() {
try {
BufferedReader br = Tools.getBuffer(s.getInputStream());
String msg = "";
while((msg=br.readLine())!=null){
Tools.msg(msg);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.softeem.streamdemo52;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("localhost",8888);
new MsgReceiver(s).start();
//输入消息
BufferedReader br = Tools.getBuffer(System.in);
String msg = "";
while((msg=br.readLine())!=null){
Tools.sendMsg2(s, msg);
}
}
}