1实训目的
通过一个聊天室的设计来综合运用所学的相关知识(Java的数据类型、Socket、用
户自定义类、异常处理等)。
2.实训内容与要求
一个简单的图形界面的聊天室程序。用户可以在图形界面下与服务器建立联系后进行一对一的聊天
3.实训思路
(1)创建服务器端程序和客户端程序的界面。
(2)定义用于发送和接收消息的方法。
(3)定义用于开启服务和连接服务的方法。
4.实训步骤
(1)创建服务器程序和客户端程序的界面。
运行结果截图:
服务器端代码如下:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ServerChat extends JFrame {
private JButton btnSend;
private JTextArea jtaRecord;
private JTextField jtfMessage;
private ServerSocket server;
private Socket connect;
private ObjectOutputStream out;
private ObjectInputStream in;
private int count = 0;
public ServerChat() {
super("服务器端");
setSize(400, 400);
setLocation(100, 100);
setResizable(false);
Container container = getContentPane();
JPanel pnlTop = new JPanel();
pnlTop.setLayout(new FlowLayout(FlowLayout.LEFT));
container.add(pnlTop, BorderLayout.NORTH);
JPanel pnlRecord = new JPanel();
pnlTop.add(new JLabel("聊天内容:"));
pnlTop.add(pnlRecord);
jtaRecord = new JTextArea(13, 35);
jtaRecord.setEditable(false);
jtaRecord.setLineWrap(true);
pnlRecord.add(jtaRecord);
JScrollPane scroll = new JScrollPane(jtaRecord);
scroll.setSize(336, 103);
pnlRecord.add(scroll);
JPanel pnlBottom = new JPanel();
pnlBottom.setLayout(new FlowLayout(FlowLayout.LEFT));
container.add(pnlBottom, BorderLayout.SOUTH);
pnlBottom.add(new JLabel("消息:"));
jtfMessage = new JTextField(25);
pnlBottom.add(jtfMessage);
btnSend = new JButton("发送");
pnlBottom.add(btnSend);
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 处理发送按钮的逻辑
String message = jtfMessage.getText(); // 获取文本框中的消息
displayMessage("服务器: " + message +"\n"); // 显示消息到聊天记录
sendMessage("服务器: "+message); // 发送消息给客户端
jtfMessage.setText(""); // 清空文本框
}
});
setVisible(true);
}
public void runServer() {
try {
server = new ServerSocket(1234);
while (true) {
try {
listenConnection();
getStream();
communication();
} catch (EOFException e) {
System.out.println("服务器终止了连接!!!");
} finally {
connect.close();
count++;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void listenConnection() throws IOException {
displayMessage("服务器已启动等待连接......\n");
connect = server.accept();
displayMessage("收到连接" + count + "从" + connect.getInetAddress().getHostName() + "\n");
}
private void getStream() throws IOException {
out = new ObjectOutputStream(connect.getOutputStream());
out.flush();
in = new ObjectInputStream(connect.getInputStream());
}
private void displayMessage(String message) {
// 显示消息的逻辑
SwingUtilities.invokeLater(() -> {
jtaRecord.append(message); // 将消息添加到聊天记录文本区域
});
}
private void communication() {
// 通信逻辑
try {
while (true) {
String message = (String) in.readObject(); // 从客户端接收消息
displayMessage("客户端: " + message + "\n"); // 显示消息到聊天记录
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
private void sendMessage(String message) {
try {
out.writeObject(message); // 将消息发送给客户端
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void closeServer() {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ServerChat server = new ServerChat();
server.runServer();
server.closeServer(); }
}
客户端代码如下:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ClientChat extends JFrame implements ActionListener {
private JButton btnSend;
private JTextArea jtaRecord;
private JTextField jtfMessage;
private ObjectOutputStream out;
private ObjectInputStream in;
private String msg="";
private Socket client;
public ClientChat() {
super("客户端");
setSize(400,400);
setLocation(100,100);
setResizable(false);
Container container=getContentPane();
JPanel pnlTop=new JPanel();
pnlTop.setLayout(new FlowLayout(FlowLayout.LEFT));
container.add(pnlTop,BorderLayout.NORTH);
JPanel pnlRecord=new JPanel();
pnlTop.add(new JLabel("聊天内容:"));
pnlTop.add(pnlRecord);
jtaRecord=new JTextArea(13,35);
jtaRecord.setEditable(false);
jtaRecord.setLineWrap(true);
pnlRecord.add(jtaRecord);
JScrollPane scroll=new JScrollPane(jtaRecord);
scroll.setSize(336,103);
pnlRecord.add(scroll);
JPanel pnlBottom=new JPanel();
pnlBottom.setLayout(new FlowLayout(FlowLayout.LEFT));
container.add(pnlBottom,BorderLayout.SOUTH);
pnlBottom.add(new JLabel("消息:"));
jtfMessage=new JTextField(25);
pnlBottom.add(jtfMessage);
btnSend=new JButton("发送");
pnlBottom.add(btnSend);
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 处理发送按钮的逻辑
String message = jtfMessage.getText(); // 获取文本框中的消息
sendData(message); // 发送消息给服务器端
jtfMessage.setText(""); // 清空文本框
}
});
setVisible(true);
}
public void runClient() {
try {
connectServer();
getStream();
communication();
}catch(EOFException e) {
System.err.println("服务器终止了连接!!!");
}catch(IOException e) {
e.printStackTrace();
}finally {
closeConnection();
}
}
private void connectServer() throws IOException{
String chatServer = "127.0.0.1";
displayMessage("正在尝试连接......\n");
client=new Socket(InetAddress.getByName(chatServer),1234);
displayMessage("已连接到:"+client.getInetAddress().getHostName()+"\n");
}
private void getStream() throws IOException {
out=new ObjectOutputStream(client.getOutputStream());
out.flush();
in=new ObjectInputStream(client.getInputStream());
}
private void communication() throws IOException {
setTextFieldEditable(true);
do {
try {
msg=(String) in.readObject();
displayMessage(" \n"+msg);
}catch(ClassNotFoundException e) {
displayMessage(" \n收到异常对象类型! \n");
}
}while(!msg.equals("服务器:stop"));
}
private void closeConnection() {
displayMessage("\n关闭连接!!!\n");
setTextFieldEditable(false);
try {
out.close();
in.close();
client.close();
}catch(IOException e) {
e.printStackTrace();
}
}
private void sendData(String msg) {
try {
out.writeObject(msg);
out.flush();
displayMessage("客户端:"+msg+"\n");
}catch(IOException e) {
jtaRecord.append("\n发生写入错误!!!");
}
}
private void displayMessage(final String msg) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jtaRecord.append(msg);
jtaRecord.setCaretPosition(jtaRecord.getText().length());
}
});
}
private void setTextFieldEditable(final boolean editable) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jtfMessage.setEditable(editable);
}
});
}
public void actionPerformed(ActionEvent event) {
sendData(jtfMessage.getText());
}
public static void main(String[] args) {
new ClientChat().runClient();
}
}