一对一聊天
2023-12-13 06:14:49
创建包
服务界面
package yiduiyi;
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Fuwuduan extends JFrame {
private JTextArea ta_info;
private ServerSocket server; // 声明ServerSocket对象
private Socket socket; // 声明Socket对象socket
private Hashtable<String, Socket> map = new Hashtable<String, Socket>();// 用于存储连接到服务器的用户和客户端套接字对象
public void createSocket() {
try {
server = new ServerSocket(1978);
while (true) {
ta_info.append("等待新客户连接......\n");
socket = server.accept();// 创建套接字对象
ta_info.append("客户端连接成功。" + socket + "\n");
new ServerThread(socket).start();// 创建并启动线程对象
}
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));// 创建输入流对象
while (true) {
String info = in.readLine();// 读取信息
String key = "";
if (info.startsWith("用户:")) {// 添加登录用户到客户端列表
key = info.substring(3, info.length());// 获得用户名并作为键使用
map.put(key, socket);// 添加键值对
Set<String> set = map.keySet();// 获得集合中所有键的Set视图
Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
while (keyIt.hasNext()) {
String receiveKey = keyIt.next();// 获得表示接收信息的键
Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
PrintWriter out = new PrintWriter(s
.getOutputStream(), true);// 创建输出流对象
Iterator<String> keyIt1 = set.iterator();// 获得所有键的迭代器
while (keyIt1.hasNext()) {
String receiveKey1 = keyIt1.next();// 获得键,用于向客户端添加用户列表
out.println(receiveKey1);// 发送信息
out.flush();// 刷新输出缓冲区
}
}
} else {// 转发接收的消息
key = info.substring(info.indexOf(":发送给:") + 5, info
.indexOf(":的信息是:"));// 获得接收方的key值,即接收方的用户名
String sendUser = info.substring(0, info
.indexOf(":发送给:"));// 获得发送方的key值,即发送方的用户名
Set<String> set = map.keySet();// 获得集合中所有键的Set视图
Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
while (keyIt.hasNext()) {
String receiveKey = keyIt.next();// 获得表示接收信息的键
if (key.equals(receiveKey)
&& !sendUser.equals(receiveKey)) {// 如果是发送方,但不是用户本身
Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
PrintWriter out = new PrintWriter(s
.getOutputStream(), true);// 创建输出流对象
out.println("MSG:"+info);// 发送信息
out.flush();// 刷新输出缓冲区
}
}
}
}
} catch (IOException e) {
ta_info.append(socket + "已经退出。\n");
}
}
}
public static void main(String args[]) {
Fuwuduan frame = new Fuwuduan();
frame.setVisible(true);
frame.createSocket();
}
public Fuwuduan() {
super();
setTitle("多个用户聊天");
setBounds(100, 100, 385, 266);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scrollPane = new JScrollPane();
getContentPane().add(scrollPane, BorderLayout.CENTER);
ta_info = new JTextArea();
scrollPane.setViewportView(ta_info);
}
}
客户界面
package yiduiyi;
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Fuwuduan extends JFrame {
private JTextArea ta_info;
private ServerSocket server; // 声明ServerSocket对象
private Socket socket; // 声明Socket对象socket
private Hashtable<String, Socket> map = new Hashtable<String, Socket>();// 用于存储连接到服务器的用户和客户端套接字对象
public void createSocket() {
try {
server = new ServerSocket(1978);
while (true) {
ta_info.append("等待新客户连接......\n");
socket = server.accept();// 创建套接字对象
ta_info.append("客户端连接成功。" + socket + "\n");
new ServerThread(socket).start();// 创建并启动线程对象
}
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));// 创建输入流对象
while (true) {
String info = in.readLine();// 读取信息
String key = "";
if (info.startsWith("用户:")) {// 添加登录用户到客户端列表
key = info.substring(3, info.length());// 获得用户名并作为键使用
map.put(key, socket);// 添加键值对
Set<String> set = map.keySet();// 获得集合中所有键的Set视图
Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
while (keyIt.hasNext()) {
String receiveKey = keyIt.next();// 获得表示接收信息的键
Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
PrintWriter out = new PrintWriter(s
.getOutputStream(), true);// 创建输出流对象
Iterator<String> keyIt1 = set.iterator();// 获得所有键的迭代器
while (keyIt1.hasNext()) {
String receiveKey1 = keyIt1.next();// 获得键,用于向客户端添加用户列表
out.println(receiveKey1);// 发送信息
out.flush();// 刷新输出缓冲区
}
}
} else {// 转发接收的消息
key = info.substring(info.indexOf(":发送给:") + 5, info
.indexOf(":的信息是:"));// 获得接收方的key值,即接收方的用户名
String sendUser = info.substring(0, info
.indexOf(":发送给:"));// 获得发送方的key值,即发送方的用户名
Set<String> set = map.keySet();// 获得集合中所有键的Set视图
Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
while (keyIt.hasNext()) {
String receiveKey = keyIt.next();// 获得表示接收信息的键
if (key.equals(receiveKey)
&& !sendUser.equals(receiveKey)) {// 如果是发送方,但不是用户本身
Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
PrintWriter out = new PrintWriter(s
.getOutputStream(), true);// 创建输出流对象
out.println("MSG:"+info);// 发送信息
out.flush();// 刷新输出缓冲区
}
}
}
}
} catch (IOException e) {
ta_info.append(socket + "已经退出。\n");
}
}
}
public static void main(String args[]) {
Fuwuduan frame = new Fuwuduan();
frame.setVisible(true);
frame.createSocket();
}
public Fuwuduan() {
super();
setTitle("多个用户聊天");
setBounds(100, 100, 385, 266);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scrollPane = new JScrollPane();
getContentPane().add(scrollPane, BorderLayout.CENTER);
ta_info = new JTextArea();
scrollPane.setViewportView(ta_info);
}
}
结果如下
文章来源:https://blog.csdn.net/s1133333/article/details/134846113
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!