import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
@SuppressWarnings("all")
public class MyServer {
//保存接收信息的端口号
static ArrayList<Integer> list = new ArrayList<>();
// 保存接收文件的端口号
static ArrayList<Integer> clientServer = new ArrayList<>();
// 保存添加用户的用户名
static ArrayList<String> clientName = new ArrayList<>();
// 分别是接收信息端口号、接收文件端口号
static int CLIEN_TPORT, CLIENT_SERVER;
// 客户端名称
static String CLIENT_NAME;
public static void main(String[] args) throws IOException {
serverFrame();
}
//初始化服务器界面
public static void serverFrame() {
//界面
JFrame jf = new JFrame("服务器");
jf.setSize(600, 500);//窗体大小
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭方式
jf.setLocationRelativeTo(null);// 居中
jf.setLayout(new FlowLayout(FlowLayout.CENTER));
// 创建组件对象
JLabel j1 = new JLabel("用户端口:\n");
JTextField t1 = new JTextField(7);// 33个字符宽
JLabel j2 = new JLabel("用户名称:");
JTextField t2 = new JTextField(7);// 33个字符宽
JLabel j3 = new JLabel("服务端口:");
JTextField t3 = new JTextField(7);// 33个字符宽
JButton b1 = new JButton("添加新用户");
JButton b2 = new JButton("启动服务器");
JButton b3 = new JButton("查看在线用户");
JTextArea area1 = new JTextArea(24, 55);
// 处理点击启动服务器按钮的事件
new Thread(new Runnable() {
@Override
public void run() {
b2.addActionListener(e -> {
area1.append("启动服务器成功!\n");
b2.setEnabled(false);
new Thread(new Runnable() {
@Override
public void run() {
serverConnect1();
}
}).start();
});
}
}).start();
// 处理点击按钮添加用户的事件
new Thread(new Runnable() {
@Override
public void run() {
b1.addActionListener(e -> {
if (t1.getText().trim().isEmpty() || t2.getText().trim().isEmpty() || t3.getText().trim().isEmpty()) {
return;
}
area1.append("添加用户\"" + t2.getText() + "\"成功!\n");
CLIEN_TPORT = Integer.parseInt(t1.getText());
CLIENT_SERVER = Integer.parseInt(t3.getText());
CLIENT_NAME = t2.getText();
list.add(CLIEN_TPORT);
clientServer.add(CLIENT_SERVER);
clientName.add(CLIENT_NAME);
new Thread(new Runnable() {
@Override
public void run() {
try {
addClient(CLIENT_NAME, CLIEN_TPORT, CLIENT_SERVER, 300, 300);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}).start();
t2.setText("");
t1.setText("");
t3.setText("");
});
}
}).start();
// 查看用户列表
new Thread(new Runnable() {
@Override
public void run() {
b3.addActionListener(e -> {
for (String s : clientName) {
area1.append("\"" + s + "\"在线中...\n");
}
});
}
}).start();
jf.add(j1);
jf.add(t1);
jf.add(j2);
jf.add(t2);
jf.add(j3);
jf.add(t3);
jf.add(b1);
jf.add(b2);
jf.add(b3);
jf.add(area1);
jf.setVisible(true);
}
public static void serverConnect1() {
//监听发送信息的线程
new Thread(() -> {
// 服务器监听
ServerSocket serverSocket1 = null;
try {
serverSocket1 = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
String[] msg = {""};
Socket socket = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
socket = serverSocket1.accept();
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
assert br != null;
msg[0] = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//接收到某个客户端请求之后开启线程进行分别转发
for (int i = 0; i < list.size(); i++) {
int finalI = i;
new Thread(() -> {
try {
Socket socket1 = new Socket("localhost", list.get(finalI));
System.out.println(CLIEN_TPORT);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
bufferedWriter.write(msg[0]);
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedWriter.close();
socket1.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}).start();
}
try {
bw.close();
br.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
//转发来自客户端的文件再转发回给客户端
new Thread(() -> {
ServerSocket serverSocket = null;
byte[] bytes = null;
try {
serverSocket = new ServerSocket(9999);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
Socket socket = null;
try {
System.out.println("ok");
socket = serverSocket.accept();
System.out.println("hh");
bytes = StreamUtils.streamToByteArray(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
try {
byte[] finalBytes = bytes;
System.out.println(finalBytes);
// 将文件转发给用户
for (int i = 0; i < clientServer.size(); i++) {
int finalI = i;
ne
java socket+JFrame实现发送文件私聊群聊功能
需积分: 0 143 浏览量
更新于2024-01-01
1
收藏 28KB ZIP 举报
Java Socket和JFrame是Java编程中的重要组成部分,用于构建网络通信和图形用户界面。在这个项目中,我们将讨论如何使用它们来实现一个具有私聊和群聊功能的文件发送系统。
`Socket`是Java提供的网络编程接口,它允许两台计算机通过网络进行双向通信。在Java中,我们可以创建一个ServerSocket监听特定的端口,等待客户端的连接请求。一旦有客户端连接,就会建立一个Socket连接,这个连接就构成了两个应用程序之间的通道,数据可以在两端之间双向传输。在这个项目中,服务器端将使用ServerSocket监听一个端口,以便接收用户的连接请求。
`JFrame`是Java Swing库中的一个组件,用于创建窗口应用程序的主框架。它提供了基本的窗口特性,如标题、边框、关闭按钮等。在这个聊天应用中,JFrame将被用来构建用户界面,展示聊天信息,并提供文件选择和发送的交互功能。
项目实现的关键步骤如下:
1. **服务器端**:创建ServerSocket,监听一个预设的端口号。当一个新的Socket连接建立时,服务器创建一个新的线程来处理该连接,以实现并发处理多个客户端的连接。对于私聊,服务器需要根据接收的消息中的目标用户信息,将消息定向转发给指定的客户端。对于群聊,服务器需要广播消息给所有已连接的客户端。
2. **客户端**:使用Socket连接服务器,创建JFrame实例展示聊天界面。用户可以输入文字信息,选择本地文件并发送。发送的信息通过Socket连接发送到服务器,服务器再将信息转发给其他用户或指定用户。
3. **文件传输**:在Java中,可以使用`FileInputStream`和`FileOutputStream`来读取和写入文件。在发送文件时,客户端将文件分割成多个数据块,逐个通过Socket发送。服务器接收到每个数据块后,存储起来,直到接收到所有数据块,然后组合成完整的文件并转发给其他客户端。
4. **消息格式**:为了区分文字信息和文件,消息需要有一个统一的格式。例如,可以将文件信息封装在一个特殊的JSON对象中,包含文件名、文件类型和文件数据的Base64编码。
5. **安全性**:考虑到文件传输的安全性,可能需要采用SSL/TLS加密技术,以保护数据在传输过程中的安全。同时,对用户的身份验证和授权也是必要的,以确保只有合法用户可以参与聊天并发送文件。
6. **异常处理**:在编程过程中,需要处理可能出现的各种异常,如网络中断、文件读写错误等,确保程序的健壮性。
7. **优化**:为了提高性能,可以考虑使用多线程处理文件传输,或者使用NIO(非阻塞I/O)以减少等待时间。
以上就是使用Java Socket和JFrame实现发送文件私聊群聊功能的基本思路和技术要点。实际项目中,还需要考虑到用户体验,如界面设计、错误提示、文件进度显示等功能,以提供更加友好的交互体验。
面向复制2021
- 粉丝: 12
- 资源: 1