本程序使用到的所有类、方法以及内部类:
基于UDP协议编写一个GUI界面的简易聊天室
开发软件:IDEA
利用UDP协议进行信息的传输与接收,由于聊天室属于即时通讯,所以必须做到同时接收与发送,因此可以考虑利用多线程完成该目的。
使用到的组件: JPanel、JScrollPane、JLabel、JTextField、JTextArea、JButton
public class UDPChatFace extends JPanel implements ActionListener {
//创建变量
JPanel panel_1;
JPanel panel_2;
JPanel panel_3;
JScrollPane panel_2_1;//滚动面板显示聊天记录
JPanel panel_2_2;
JLabel label1;//监听
JLabel label2;//ip
JLabel label3;//端口
JTextField textField_ip;//ip输入
JTextField textField_port;//端口号输入
JTextArea textArea_history;//聊天记录文本域
JTextArea textArea_message;//输入文字信息文本域
JButton button_concern;
JButton button_send;
JButton button_clear;
//端口设置
//一般设置在8000以上,8000以下的端口号大部分被占用
private int localPort = 10001;//本地端口
private int otherPort = 10002;//对方端口
private String ip;
String message;//输入框信息
private DatagramSocket socket;
public UDPChatFace(){
init();
}
public void init(){
//添加组件
panel_1 = new JPanel();
panel_2 = new JPanel();
panel_3 = new JPanel();
textArea_history = new JTextArea(40,68);//设置聊天记录框的大小
textArea_history.setEditable(false);//设置聊天记录框不可输入
textArea_message = new JTextArea(13,70);
textArea_message.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) { //键盘监听事件,实现文本框输入后,按回车消息发送的功能
if (e.getKeyCode() == KeyEvent.VK_ENTER){
if (textArea_message.getText().equals("")){
JOptionPane.showMessageDialog(panel_1,"不可发送空白信息!"); //弹窗
return;
}else {
send(); //发送消息
}
}
}
});
panel_2_1 = new JScrollPane(textArea_history); //将"聊天记录"输入框加入滚动面板中
panel_2_1.setBorder(BorderFactory.createTitledBorder("聊天记录"));//边框设置
panel_2_2 = new JPanel();
panel_2_2.setBorder(BorderFactory.createTitledBorder("请输入文字:"));//边框设置
String str = "正在监听****端口";//标签
label1 = new JLabel(str,JLabel.RIGHT);//靠右对齐
label2 = new JLabel("请输入对方IP:",JLabel.RIGHT);
label3 = new JLabel("请输入对方端口号:",JLabel.RIGHT);
textField_ip = new JTextField(5);
textField_port = new JTextField(5);
//绑定事件
button_send = new JButton("发送");
button_send.addActionListener(this);
button_clear = new JButton("清空");
button_clear.addActionListener(this);
button_concern = new JButton("确定");
button_concern.addActionListener(this);
setLayout(new BorderLayout());
add(panel_1,BorderLayout.NORTH);
add(panel_2,BorderLayout.CENTER);
add(panel_3,BorderLayout.SOUTH);
panel_1.setLayout(new FlowLayout());
panel_1.add(label1);
panel_2.setLayout(new GridLayout(2,1));
panel_2.add(panel_2_1);
panel_2.add(panel_2_2);
panel_2_2.add(textArea_message);
panel_3.setLayout(new FlowLayout());
panel_3.add(label2);
panel_3.add(textField_ip);
panel_3.add(label3);
panel_3.add(textField_port);
panel_3.add(button_concern);
panel_3.add(button_send);
panel_3.add(button_clear);
......
}
功能:实现对方IP以及端口号的输入,建立聊天,同时开启接收信息的监听线程
//监听事件
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (button_send.equals(source)){//发送
......
}else if (button_clear.equals(source)){//清空
......
}else if (button_concern.equals(source)){//确定
if (textField_ip.getText().equals("") || textField_port.getText().equals("")){
JOptionPane.showMessageDialog(this,"未正确输入IP及端口号!");//弹窗
}else {
label1.setText("正在监听" + textField_port.getText() + "端口");
ip = textField_ip.getText();
otherPort = Integer.parseInt(textField_port.getText());
if (otherPort == 10002){
localPort = 10001;
}
else {
localPort = 10002;
}
new Receive().start();//启动监听线程
System.out.println(localPort);
System.out.println(otherPort);
button_concern.setEnabled(false);//设置按钮不可再点击
}
}
}
功能:实现聊天记录的清空
//监听事件
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (button_send.equals(source)){//发送
......
}else if (button_clear.equals(source)){//清空
textArea_history.setText("");
}else if (button_concern.equals(source)){//确定
......
}
}
功能:实现数据的发送
//监听事件
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (button_send.equals(source)){//发送
if (textArea_message.getText().equals("")){
JOptionPane.showMessageDialog(this,"不可发送空白信息!");
}else {
send();
}
}else if (button_clear.equals(source)){//清空
......
}else if (button_concern.equals(source)){//确定
......
}
public void init(){
......
//节约空间,防止每次发送数据都会new一个对象
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
}
//用于文本框内信息的发送
private void sendMessage(byte[] data){
System.out.println("消息发送成功");
try {
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(ip), localPort);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
//发送消息
private void send(){
message = textArea_message.getText();
byte[] data = message.getBytes();
sendMessage(data);
String str = "我对" + ip + ":" + otherPort + "说:" + message + '\n';
textArea_history.append(str);//添加进聊天记录框
textArea_message.setText("");//清空输入信息框
}
功能:实现信息的同步发送与接收
//程序运行时需要同步接收与发送,因此应该使用多线程,new一个线程用于接收消息
private class Receive extends Thread{
@Override
public void run() {
System.out.println("监听正在运行");
DatagramPacket packet = null;
try {
socket = new DatagramSocket(otherPort);
System.out.println("监听" + otherPort);
byte[] data = new byte[1024*4];
packet = new DatagramPacket(data, data.length);
while (true){
socket.receive(packet);
byte[] bytes = packet.getData();
String message = new String(bytes,0,bytes.length);
String str = ip + ":" + localPort + "对我说:" + message + '\n';
textArea_history.append(str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import javax.swing.*;
/**
* 启动程序
* @author TT
* @create 2020-06-16-0:53
*/
public class UDPChat extends JFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("聊天室GUI版");
frame.add(new UDPChatFace());//注意次序,add方法在前面
frame.setVisible(true);
frame.setSize(800,600);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
说说博主的一些关于UDP的小想法,适用于刚接触UDP协议的小白:
看完的你可以收藏点赞哦o( ̄▽ ̄)ブ!
转载麻烦告知并标明出处!
本文地址:https://blog.csdn.net/ttbro/article/details/106799011
如对本文有疑问, 点击进行留言回复!!
荐 【SpringMVC】001-SpringMVC入门程序(超详细版)
字节流、字符流(IO流、字节流、字符流、异常处理、Properties)
Java中Arrays.sort()的三种常用用法(自定义排序规则)
网友评论