java网络程序设计 聊天室之私聊、群聊和清屏功能的实现

本篇博客介绍了使用Java实现的TCP聊天室,具备私聊、群聊和清屏功能。服务器端会为每个客户端创建处理线程,维护用户和客户端套接字的映射,所有聊天消息通过服务器转发。同时,客户端可以查看在线用户列表。源代码链接和详细技术要点一并提供。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP聊天室实现了私聊、群聊和清屏的功能,简陋的UI界面,一个服务器端,支持多个客户端之间的通信。

项目代码:https://pan.baidu.com/s/17iegRam4KnWvcWHw3mvpxg 提取码:e8gx

服务器端:

可以开多个客户端进行客户端之间的通信。

客户端:

 

系统功能简介:

1.客户端登录成功后可以查看聊天室用户列表,并可以进行个人聊天和群聊。

 

2.服务器启动后绑定端口侦听客户端连接,并为每个客户端创建一个处理线程。服务器维护一个包括有用户和客户端套接字的用户列表。

3.所有的聊天消息都通过服务器转发完成,服务器将接收客户端聊天消息转发到指定目的地。客户端只获知其他用户的用户名,无法知道其网络信息。

4.显示聊天室在线的人数。

技术要点说明:
(1)聊天室LOGIN、LOGOUT、USERLIST、TALKTO、TALKTO_ALL等报文类型。程序中使用DataOutputStream中writeUTF()方法完成消息报文的读写。不使用BufferedReader中read Line()的原因是该方法只能读取一行文本,如何消息是包括有换行符的多行文本,则无法识别。
(2)将信息报文的发送、接受封装在Utils工具类中。
(3)使用JList控件显示客户端的用户列表。控件的数据保存在DefaultListModel数据模型对象中。

(4)由于聊天室的用户名不能相同,服务器端使用HashMap<String,Socket>存放每个用户和客户端套接字的映射。

下面附上完整代码

Utils工具类:

package wechat;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JTextArea;
import javax.xml.crypto.Data;
import org.omg.CORBA.Any;
import org.omg.CORBA.DataInputStream;
//将消息报文的发送、接受封装在Utils工具类中
public class Utils {
//通过套接字S发送字符串
public static void sendMsg(Socket s,String msg){
try{
//字符流
DataOutputStream dos =new DataOutputStream(s.getOutputStream());
dos.writeUTF(msg);
dos.flush();
}catch(IOException e){
e.printStackTrace();
}
}

//在套接字S上读取字符串,如果TCP连接关闭,返回null
public static String recvMsg(Socket s) throws IOException{
String msg=null;
DataInputStream dis=(DataInputStream) new java.io.DataInputStream(s.getInputStream());
msg=((java.io.DataInputStream) dis).readUTF();
return msg;

}
//获取格式化的当前时间字符串形式
public static String getTimeStr(){
SimpleDateFormat fm=new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");

return fm.format(new Date());

}
//添加消息到文本记录框JTextArea ,并且滚动显示到最后一行
public static void addMsgRec(JTextArea textArea,String msg){
textArea.append(msg+"\n");
textArea.setCaretPosition(textArea.getText().length());
}
}

 

服务端: 

 

package wechat;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.HashMap;
import javax.swing.AbstractButton;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
public class ChatServer {
// 添加用于功能实现的成员变量
/**
* 服务器套接字
*/
private ServerSocket server;

/**
* 判断服务器是否在运行
*/
private boolean isRunning;

/**
* 客户端映射,key -> String:客户端名称; value -> ClientHandler: 客户端处理线程
*/
//用户名不能相同,使用HashMap<String, ClientHandler>存放每个用户和客户端套接字的映射。
private HashMap<String, ClientHandler> clientHandlerMap = new HashMap<String, ClientHandler>();
private JFrame frmTcp;
private JTextField textServerIP;//ip 
private JTextField textPort;//端口
private JTable tblUsers;//在线用户列表
private JButton btnStart;//启动
private JButton btnStop;//停止
private JTextArea textAreaRecord;//文本记录框

/**
* Launch the application.
*/
//主函数
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ChatServer window = new ChatServer();
window.frmTcp.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}


/**
* Create the application.
*/
public ChatServer() {
initialize();
}


/**
* Initialize the contents of the frame.
*/
//服务器界面
private void initialize() {
frmTcp = new JFrame();
frmTcp.setResizable(false);
frmTcp.setTitle("TCP\u804A\u5929\u5BA4\u670D\u52A1\u5668");
frmTcp.setBounds(100, 100, 700, 509);
frmTcp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmTcp.getContentPane().setLayout(null);

//IP框
JLabel lblip = new JLabel("\u670D\u52A1\u5668IP\u5730\u5740:");
lblip.setBounds(10, 27, 105, 18);
frmTcp.getContentPane().add(lblip);
textServerIP = new JTextField();
textServerIP.setText("0.0.0.0");
textServerIP.setBounds(114, 24, 141, 24);
frmTcp.getContentPane().add(textServerIP);
textServerIP.setColumns(10);
//端口框
JLabel label = new JLabel("\u7AEF\u53E3\u53F7:");
label.setBounds(293, 27, 72, 18);
frmTcp.getContentPane().add(label);
textPort = new JTextField();
textPort.setText("8000");
textPort.setBounds(356, 24, 86, 24);
frmTcp.getContentPane().add(textPort);
textPort.setColumns(10);
//开始按钮
btnStart = new JButton("\u542F\u52A8");
btnStart.setBounds(479, 23, 95, 27);

评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值