Java面向对象实现简单聊天室的问题,希望大哥大姐们帮我看看
关于Java中sockets网络聊天室的简单实现。```
/*ChatClient.java*/
package cn.java.work.test6.Tcp;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import
import
import
import
import
import
import java.nio.channels.ServerSocketChannel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
public class ChatClient extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
JTextArea jTextArea; // 多行文本
JLabel jlab1; // 标签
JTextField jTextSend; // 单行文本
JButton jButtonSend;// 按钮
JLabel jlPort; // 端口 标签
JTextField jtPort;
JLabel jlIp;// 服务器 标签
JTextField jtIp;
JButton jButtonStart; // 启动服务器按钮
JButton jButtonClear; // 清除聊天记录
ServerSocket serverSocket; // 用于TCP通信前的连接
Socket server; // TCP数据收发通信
BufferedReader cin; // 字符输入
PrintStream cout;
public ChatClient() {
this.setSize(600, 500);
this.setVisible(true);
this.setTitle("TCP聊天客户端");
// 设置当前窗体 上的图形组件 手动布局
this.setLayout(null);
// 窗口加标签
jlab1 = new JLabel("内容:");
// jlab1.setSize(60, 20); // 标签图形 宽、高
// jlab1.setLocation(20, 10);
jlab1.setBounds(20, 10, 60, 20);
jlab1.setVisible(true); // 标签可见,不隐藏
this.add(jlab1);
jTextArea = new JTextArea();
jTextArea.setBounds(20, 40, 550, 300);
// jTextArea.setBackground(Color.red); // 文本区 红色背景
jTextArea.setVisible(true);
this.add(jTextArea);
// 单行文本
jTextSend = new JTextField("");
jTextSend.setBounds(20, 350, 470, 30);
jTextSend.setVisible(true);
// jTextSend.getText(); // 读取文本框内的字符串
this.add(jTextSend);
// 按钮 :发送
jButtonSend = new JButton("发送");
jButtonSend.setBounds(500, 350, 60, 30);
jButtonSend.setVisible(true);
// 给按钮 加 监视器/监听器
jButtonSend.addActionListener(this);
this.add(jButtonSend);
// 加服务器标签
jlPort = new JLabel("服务器");
jlPort.setBounds(20, 390, 60, 30);
jlPort.setVisible(true);
this.add(jlPort);
// 填IP号 的 文本框
jtPort = new JTextField("127.0.0.1");
jtPort.setBounds(70, 390, 60, 30);
jtPort.setVisible(true);
this.add(jtPort);
// 加端口标签
jlPort = new JLabel("端口");
jlPort.setBounds(170, 390, 60, 30);
jlPort.setVisible(true);
this.add(jlPort);
// 填端口号 的 文本框
jtPort = new JTextField("8080");
jtPort.setBounds(220, 390, 60, 30);
jtPort.setVisible(true);
this.add(jtPort);
// 加 连接TCP聊天服务 按钮
jButtonStart = new JButton("连接TCP服务器");
jButtonStart.setBounds(340, 390, 125, 30);
jButtonStart.setVisible(true);
jButtonStart.addActionListener(this); // 监听 按钮
this.add(jButtonStart);
// 加 清除聊天屏幕 按钮
jButtonClear = new JButton("清屏");
jButtonClear.setBounds(500, 390, 60, 30);
jButtonClear.setVisible(true);
jButtonClear.addActionListener(this); // 监听按钮 单击事件
this.add(jButtonClear);
// 刷新窗体
this.repaint();
}
// 实现事件处理方法:actionPerformed 鼠标单击事件处理
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jButtonSend) {
// 读取文本框的文本
String strSend = jTextSend.getText();
// 发送的文本填到 文本区对象
jTextArea.append(strSend + "\n");
// 发送的文本填到 TCP === cout
cout.println(strSend);
// 发送文本框清零
jTextSend.setText("");
} else if (e.getSource() == jButtonClear) { // 清除按钮 事件处理
// 清空文本区
jTextArea.setText("");
} else if (e.getSource() == jButtonStart) {
// 启动TCP网络通信服务,等待客户端连接 重点!!
try {
String serverAddress = jtIp.getText();
int port = Integer.parseInt(jtPort.getText());
server = new Socket(serverAddress, port);
// 1、服务器建立TCP连接控制对象
serverSocket = new ServerSocket(port); // 服务器TCP端口是8080
// 2、监听:等待 ,客户端连接,阻塞
server = serverSocket.accept(); // 一旦有客户端主动连接我服务器,立即返回一个Socket对象
// 3、TCP通信的数据流:连接执行到这里,说明 双方已经连接好了,可以通信了
// server.getInputStream(); // TCP接收数据的字节流/管道
// server.getOutputStream(); // TCP发送数据的字节流/管道
// ------> 这一步,说明TCP连接就已经建立了
// cin -----> 绑定 了TCP InputStream
// cout ----> 绑定 了TCP OutputStream
cin = new BufferedReader(new InputStreamReader(server.getInputStream()));
cout = new PrintStream(server.getOutputStream());
// 4、接收TCP数据 cin.readLine()
// 向聊天记录文本区,加接收的字符串
// jTextArea.append(cin.readLine());
// 改进:多次接收,不定时===》 定义一个接收数据的 线程 === 一直等待接收数据,然后放入聊天区
// 接收后做1件事:1、把数据放入聊天区
ServerRec ServerReciver = new ServerRec(); //
ServerReciver.start();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
// 服务器接收TCP数据的线程
class ServerRec extends Thread {
public void run() {
while (true) {
String recv;
try {
// 1、读取一行字符串
recv = cin.readLine(); // 阻塞
// 2、把数据放入聊天区
jTextArea.append("服务器:" + recv + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new ChatClient();
}
}
```
```
/*ChatServer.java*/
package cn.java.work.test6.Tcp;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import
import
import
import
import
import
import java.nio.channels.ServerSocketChannel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
public class ChatServer extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
JTextArea jTextArea; // 多行文本
JLabel jlab1; // 标签
JTextField jTextSend; // 单行文本
JButton jButtonSend;// 按钮
JLabel jlPort; // 端口 标签
JTextField jtPort;
JButton jButtonStart; // 启动服务器按钮
JButton jButtonClear; // 清除聊天记录
ServerSocket serverSocket; // 用于TCP通信前的连接
Socket server; // TCP数据收发通信
BufferedReader cin; // 字符输入
PrintStream cout;
public ChatServer() {
this.setSize(600, 500);
this.setVisible(true);
this.setTitle("TCP聊天服务器");
// 设置当前窗体 上的图形组件 手动布局
this.setLayout(null);
// 窗口加标签
jlab1 = new JLabel("内容:");
// jlab1.setSize(60, 20); // 标签图形 宽、高
// jlab1.setLocation(20, 10);
jlab1.setBounds(20, 10, 60, 20);
jlab1.setVisible(true); // 标签可见,不隐藏
this.add(jlab1);
jTextArea = new JTextArea();
jTextArea.setBounds(20, 40, 550, 300);
// jTextArea.setBackground(Color.red); // 文本区 红色背景
jTextArea.setVisible(true);
this.add(jTextArea);
// 单行文本
jTextSend = new JTextField("");
jTextSend.setBounds(20, 350, 470, 30);
jTextSend.setVisible(true);
// jTextSend.getText(); // 读取文本框内的字符串
this.add(jTextSend);
// 按钮 :发送
jButtonSend = new JButton("发送");
jButtonSend.setBounds(500, 350, 60, 30);
jButtonSend.setVisible(true);
// 给按钮 加 监视器/监听器
jButtonSend.addActionListener(this);
this.add(jButtonSend);
// 加端口标签
jlPort = new JLabel("端口");
jlPort.setBounds(70, 390, 60, 30);
jlPort.setVisible(true);
this.add(jlPort);
// 填端口号 的 文本框
jtPort = new JTextField("8080");
jtPort.setBounds(120, 390, 60, 30);
jtPort.setVisible(true);
this.add(jtPort);
// 加 启动TCP聊天服务 按钮
jButtonStart = new JButton("启动TCP服务器");
jButtonStart.setBounds(240, 390, 125, 30);
jButtonStart.setVisible(true);
jButtonStart.addActionListener(this); // 监听 按钮
this.add(jButtonStart);
// 加 清除聊天屏幕 按钮
jButtonClear = new JButton("清屏");
jButtonClear.setBounds(500, 390, 60, 30);
jButtonClear.setVisible(true);
jButtonClear.addActionListener(this); // 监听按钮 单击事件
this.add(jButtonClear);
// 刷新窗体
this.repaint();
}
// 实现事件处理方法:actionPerformed 鼠标单击事件处理
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jButtonSend) {
// 读取文本框的文本
String strSend = jTextSend.getText();
// 发送的文本填到 文本区对象
jTextArea.append(strSend + "\n");
// 发送的文本填到 TCP === cout
cout.println(strSend);
// 发送文本框清零
jTextSend.setText("");
} else if (e.getSource() == jButtonClear) { // 清除按钮 事件处理
// 清空文本区
jTextArea.setText("");
} else if (e.getSource() == jButtonStart) {
// 启动TCP网络通信服务,等待客户端连接 重点!!
try {
// String serverAddress = jtIp.getText();
int port = Integer.parseInt(jtPort.getText());
// server = new Socket(serverAddress, port);
// 1、服务器建立TCP连接控制对象
serverSocket = new ServerSocket(port); // 服务器TCP端口是8080
// 2、监听:等待 ,客户端连接,阻塞
server = serverSocket.accept(); // 一旦有客户端主动连接我服务器,立即返回一个Socket对象
// 3、TCP通信的数据流:连接执行到这里,说明 双方已经连接好了,可以通信了
// server.getInputStream(); // TCP接收数据的字节流/管道
// server.getOutputStream(); // TCP发送数据的字节流/管道
// ------> 这一步,说明TCP连接就已经建立了
// cin -----> 绑定 了TCP InputStream
// cout ----> 绑定 了TCP OutputStream
cin = new BufferedReader(new InputStreamReader(server.getInputStream()));
cout = new PrintStream(server.getOutputStream());
// 4、接收TCP数据 cin.readLine()
// 向聊天记录文本区,加接收的字符串
// jTextArea.append(cin.readLine());
// 改进:多次接收,不定时===》 定义一个接收数据的 线程 === 一直等待接收数据,然后放入聊天区
// 接收后做1件事:1、把数据放入聊天区
ServerRec ServerReciver = new ServerRec(); //
ServerReciver.start();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
// 服务器接收TCP数据的线程
class ServerRec extends Thread {
public void run() {
while (true) {
String recv;
try {
// 1、读取一行字符串
recv = cin.readLine(); // 阻塞
// 2、把数据放入聊天区
jTextArea.append("客户端:" + recv + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new ChatServer();
}
}
```
一个是服务器的,一个是客户端的,图形界面已经设置了一些,但是怎么将服务器与客户端进行连通并实现简单聊天呢??需要热心的朋友们帮我看看并补充一些相关代码。非常感谢