实验报告(三)
实验目的
熟悉 Java 综合应用程序的开发。
实验任务
编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是“欢迎使用 XXX 聊天室应用”,其中 XXX 是自己的班级姓名学号,如“软件 171 张三 1234”。
源代码
Client.java
/**
* @AUTHOR Prince
* @TIME 2020/11/12 18:50
*/
package com.science.sc3;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Client {
public static JTextField sendBox = null;
public static JButton sendBtn = null;
public static JTextArea receiveArea = null;
public static Socket socket = null;
public static InputStream inputStream = null;
public static OutputStream outputStream = null;
public static void main(String[] args) throws IOException {
socket = new Socket("127.0.0.1",8989);
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
init();
new Thread(Receive.getInstance()).start();
}
//初始化窗口
public static void init(){
JFrame jFrame = new JFrame("欢迎使用 软件19X XXX 1906300XXX 聊天室应用");
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel jPanel = new JPanel();
jFrame.setContentPane(jPanel);
jPanel.setLayout(new BorderLayout());
jFrame.setSize(600,800);
JTextField jTextField = new JTextField();
jTextField.setPreferredSize(new Dimension(0,30));
jPanel.add(jTextField,BorderLayout.SOUTH);
JPanel jPanel1 = new JPanel();
jPanel1.setPreferredSize(new Dimension(0,30));
jPanel1.setLayout(new BorderLayout());
jPanel1.add(jTextField,BorderLayout.CENTER);
JButton jButton = new JButton("发送");
jPanel1.add(jButton,BorderLayout.EAST);
JTextArea jTextArea = new JTextArea();
jTextArea.setEditable(false);
JScrollPane jScrollPane = new JScrollPane(jTextArea);
jPanel.add(jScrollPane,BorderLayout.CENTER);
jPanel.add(jPanel1,BorderLayout.SOUTH);
jFrame.setVisible(true);
jFrame.setLocationRelativeTo(null);
sendBox = jTextField;
sendBtn = jButton;
receiveArea = jTextArea;
sendBtn.addActionListener(e -> sendEvent());
sendBox.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == 13){
sendEvent();
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}
//发送消息
public static void sendEvent(){
String msg = sendBox.getText();
try {
if(!"".equals(msg)){
sendBox.setText("");
System.out.println(msg);
byte[] data = msg.getBytes();
outputStream.write(data);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器已断开!");
System.exit(9999);
}
}
//接受消息
public static class Receive implements Runnable{
byte[] data = new byte[1024];
int len = 0;
private static Receive instance = null;
public static Receive getInstance(){
if(instance == null){
instance = new Receive();
}
return instance;
}
private Receive(){}
@Override
public void run() {
try {
while ((len = inputStream.read(data)) != -1) {
append(data,len);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("服务器已断开!");
System.exit(9999);
}
}
public SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
public void append(byte[] data,int len){
String s = new String(data,0,len);
receiveArea.append("\n");
receiveArea.append(sdf.format(new Date()));
receiveArea.append("\n");
receiveArea.append(s);
}
}
}
Server.java
/**
* @AUTHOR Prince
* @TIME 2020/11/12 18:51
*/
package com.science.sc3;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
public class Server {
public static ServerSocket serverSocket = null;
public static LinkedList<MySocket> list = null;
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(8989);
list = new LinkedList<>();
System.out.println("服务器启动");
new Thread(new SocketAccept()).start();
}
//接受客户端连接
public static class SocketAccept implements Runnable {
@Override
public void run() {
try {
while (true) {
Socket accept = serverSocket.accept();
MySocket mySocket = new MySocket(accept);
list.add(mySocket);
new Thread(new ReceiveAndSend(mySocket)).start();
System.out.println(accept.getLocalAddress().getHostName() + " " + accept.getLocalAddress().getHostAddress() + " 已连接");
}
} catch (Exception e) {
}
}
}
public static class ReceiveAndSend implements Runnable {
private MySocket mySocket = null;
byte[] data = new byte[1024];
int len = 0;
ReceiveAndSend(MySocket mySocket) {
this.mySocket = mySocket;
}
@Override
public void run() {
try {
while ((len = mySocket.inputStream.read(data)) != -1) {
System.out.println(mySocket.socket.getLocalAddress().getHostName() + " " + mySocket.socket.getLocalAddress().getHostAddress() + " 发送一条消息:");
System.out.println(new String(data,0,len));
for (MySocket socket : list) {
try {
socket.outputStream.write(data,0,len);
} catch (IOException e) {
list.remove(socket);
}
}
}
} catch (Exception e) {
list.remove(mySocket);
}
}
}
public static class MySocket {
public Socket socket = null;
public InputStream inputStream = null;
public OutputStream outputStream = null;
MySocket(Socket socket) throws IOException {
this.socket = socket;
this.inputStream = socket.getInputStream();
this.outputStream = socket.getOutputStream();
}
}
}