失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Java实现简易UDP客户端 服务器端通信程序

Java实现简易UDP客户端 服务器端通信程序

时间:2022-03-07 20:41:42

相关推荐

Java实现简易UDP客户端 服务器端通信程序

本学期计算机网络课程要求完成一个TCP和一个UDP的通信程序,我完成了功能的简单实现。我在上一篇博客已经讲了TCP的具体实现,接下来讲一讲UDP程序的实现。


目录

效果展示一、项目结构二、完整代码1.UDPClient2.UDPServer3.UDPFrame4.UDPSend5.UDPReceive6.ReminderTextAdapter(参考别人的,非原创)总结

效果展示

以下是具体实现过程:

一、项目结构

下面说说每个类的具体作用:

UDPClient:UDP客户端的核心代码部分;

UDPServer:UDP服务器端的核心代码部分;

UDPFrame:UDP客户端和服务器端的界面搭建;

UDPSend:UDP客户端或服务器端的一端向另一端发送消息;

UDPReceive:UDP客户端或服务器端的一端接收另一端发送的消息;

ReminderTextAdapter:网上查阅的代码,非核心内容实现部分,主要用于灰色提示字hint功能的实现(swing中的实现方法不太熟悉);

注:在UDP通信中,没有TCP那样明确的ServerSocket,只是通过Datagram数据报的方式传递给另外的DatagramSocket,因此本项目中虽然有客户端与服务器端的区别,但本质上二者并无区别(即客户端与服务器端实现方式基本相同),因此客户端和服务器端需要的界面布局也相同,故我也把二者的界面抽取成了一个类,在此特地说明一下。

二、完整代码

1.UDPClient

代码如下:

package udpCommunication;import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import .DatagramPacket;import .DatagramSocket;public class UDPClient implements ActionListener, Runnable {private DatagramSocket datagramSocket;private Thread thread = null;private UDPFrame clientFrame;public UDPClient() {JPanel panel = new JPanel();clientFrame = new UDPFrame("UDPClient");clientFrame.add(panel);clientFrame.placeComponents(panel);clientFrame.setVisible(true);clientFrame.getConnect().addActionListener(e -> {try {//host:"127.0.0.1"//String host = UDPClientFrame.getIpField().getText();//port:8887int dSocketPort = Integer.parseInt(clientFrame.getDSocketField().getText());datagramSocket = new DatagramSocket(dSocketPort);clientFrame.getTextArea().append("[连接] : 正在连接中……\n");clientFrame.getTextArea().append("\t连接成功\n");thread = new Thread(this);thread.setPriority(Thread.MIN_PRIORITY);thread.start();} catch (IOException ex) {ex.printStackTrace();}});clientFrame.getTransmit().addActionListener(this);clientFrame.getTextArea().append("……UDP客户端启动……\n");System.out.println("……UDP客户端启动……\n");}public static void main(String[] args) {new UDPClient();}//向服务器端发送数据@Overridepublic void actionPerformed(ActionEvent e) {//String send = UDPClientFrame.getSendField().getText();//port:8888//发送消息new UDPSend(datagramSocket, clientFrame, "客户端").sendMessages();}//使用线程处理客户端接收服务器端的数据@Overridepublic void run() {byte[] bytes = new byte[1024];DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);new UDPReceive(datagramSocket, datagramPacket, clientFrame, "服务器端").receiveMessages();}}

2.UDPServer

代码如下:

package udpCommunication;import javax.swing.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import .*;public class UDPServer implements ActionListener, Runnable {private DatagramSocket datagramSocket;private Thread thread = null;private UDPFrame serverFrame;public UDPServer() {serverFrame = new UDPFrame("UDPServer");JPanel panel = new JPanel();serverFrame.add(panel);serverFrame.placeComponents(panel);serverFrame.setVisible(true);//port:8888serverFrame.getConnect().addActionListener(e -> {try {int dSocketPort = Integer.parseInt(serverFrame.getDSocketField().getText());datagramSocket = new DatagramSocket(dSocketPort);serverFrame.getTextArea().append("[连接] : 正在连接中……\n");serverFrame.getTextArea().append("\t连接成功\n");thread = new Thread(this);thread.setPriority(Thread.MIN_PRIORITY);thread.start();} catch (IOException ex) {ex.printStackTrace();}});serverFrame.getTransmit().addActionListener(this);serverFrame.getTextArea().append("……UDP服务器启动……\n");System.out.println("……UDP服务器启动……\n");}public static void main(String[] args) {new UDPServer();}//向客户端发送数据@Overridepublic void actionPerformed(ActionEvent e) {new UDPSend(datagramSocket, serverFrame, "服务器端").sendMessages();}//使用线程处理服务器端接收客户端的数据@Overridepublic void run() {byte[] bytes = new byte[1024];DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);new UDPReceive(datagramSocket, datagramPacket, serverFrame, "客户端").receiveMessages();}}

3.UDPFrame

代码如下:

package udpCommunication;import javax.swing.*;import java.awt.*;/*** ip* DatagramSocket(hint:port)* DatagramPacket(hint:port)* send* showArea*/public class UDPFrame extends JFrame {private static JTextField ipField;private static JTextField dSocketField;private static JTextField dPacketField;private static JTextField sendField;private static JTextArea textArea;private static JButton connect;private static JButton transmit;public UDPFrame(String title) {setSize(700, 480);setLocationRelativeTo(null);//居中显示setResizable(false);//设置不允许改变窗体大小setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setTitle(title);}public JTextField getIpField() {return ipField;}public JTextField getDSocketField() {return dSocketField;}public JTextField getDPacketField() {return dPacketField;}public JTextField getSendField() {return sendField;}public JTextArea getTextArea() {return textArea;}public JButton getConnect() {return connect;}public JButton getTransmit() {return transmit;}public static void placeComponents(JPanel panel) {panel.setLayout(null);Font font1 = new Font("宋体", Font.BOLD, 16);Font font2 = new Font("宋体", Font.PLAIN, 16);//创建JLabelJLabel ip = new JLabel("IP");ip.setFont(font1);//设置JLabel的字体ip.setBounds(80, 30, 135, 30);panel.add(ip);JLabel dSocketLabel = new JLabel("DatagramSocket");dSocketLabel.setFont(font1);dSocketLabel.setBounds(80, 65, 135, 30);panel.add(dSocketLabel);JLabel dPacketLabel = new JLabel("DatagramPacket");dPacketLabel.setFont(font1);dPacketLabel.setBounds(80, 100, 135, 30);panel.add(dPacketLabel);JLabel send = new JLabel("Send");send.setFont(font1);send.setBounds(80, 135, 135, 30);panel.add(send);JLabel text = new JLabel("Text");text.setFont(font1);text.setBounds(80, 170, 135, 30);panel.add(text);//创建文本域ipField = new JTextField(30);ipField.setFont(font2);ipField.addFocusListener(new ReminderTextAdapter(ipField, "默认:127.0.0.1"));ipField.setBounds(220, 30, 360, 30);panel.add(ipField);dSocketField = new JTextField(30);dSocketField.setFont(font2);dSocketField.addFocusListener(new ReminderTextAdapter(dSocketField, "port:"));dSocketField.setBounds(220, 65, 360, 30);panel.add(dSocketField);dPacketField = new JTextField(30);dPacketField.setFont(font2);dPacketField.addFocusListener(new ReminderTextAdapter(dPacketField, "port:"));dPacketField.setBounds(220, 100, 360, 30);panel.add(dPacketField);sendField = new JTextField(30);sendField.setFont(font2);sendField.addFocusListener(new ReminderTextAdapter(sendField, "请输入要发送的信息:"));sendField.setBounds(220, 135, 360, 30);panel.add(sendField);textArea = new JTextArea();textArea.setFont(font2);textArea.setBounds(220, 170, 360, 160);textArea.setEditable(false);textArea.setLineWrap(false);panel.add(textArea);//给textArea添加滚动条JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(220, 170, 360, 160);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);panel.add(scrollPane);scrollPane.setViewportView(textArea);//添加两个按钮connect = new JButton("连接");connect.setFont(font1);connect.setBounds(140, 360, 115, 40);panel.add(connect);transmit = new JButton("发送");transmit.setFont(font1);transmit.setBounds(440, 360, 115, 40);panel.add(transmit);}}

4.UDPSend

代码如下:

package udpCommunication;import .DatagramPacket;import .DatagramSocket;import .InetAddress;public class UDPSend {private DatagramSocket datagramSocket;private UDPFrame udpFrame;private String sender;public UDPSend(DatagramSocket datagramSocket, UDPFrame udpFrame, String sender) {this.datagramSocket = datagramSocket;this.udpFrame = udpFrame;this.sender = sender;}public void sendMessages() {//String send = UDPServerFrame.getSendField().getText();//发送消息try {System.out.println("请输入" + sender + "要发送的消息:");String data = udpFrame.getSendField().getText();String ip = udpFrame.getIpField().getText();int dPacketPort = Integer.parseInt(udpFrame.getDPacketField().getText());byte[] bytes = data.getBytes();InetAddress inetAddress = InetAddress.getByName(ip);DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, inetAddress, dPacketPort);datagramSocket.send(datagramPacket);//udpFrame.getTextArea().append("\t" + sender + "发送消息成功\n");udpFrame.getTextArea().append("\t\t\t[" + sender + "] : " + data + "\n");String ipAddress = datagramPacket.getAddress().getHostAddress();System.out.println("ipAddress: " + ipAddress);System.out.println("ipField().getText(): " + ip);} catch (Exception ex) {ex.printStackTrace();udpFrame.getTextArea().append("\t" + sender + "尚未连接成功,消息发送失败\n");} finally {//System.out.println("\t"+sender+"发送消息成功\n");}}}

5.UDPReceive

代码如下:

package udpCommunication;import .DatagramPacket;import .DatagramSocket;public class UDPReceive {private DatagramSocket datagramSocket;private DatagramPacket datagramPacket;private UDPFrame udpFrame;private String sender;public UDPReceive(DatagramSocket datagramSocket, DatagramPacket datagramPacket, UDPFrame udpFrame, String sender) {this.datagramSocket = datagramSocket;this.datagramPacket = datagramPacket;this.udpFrame = udpFrame;this.sender = sender;}public void receiveMessages() {try {while (true) {byte[] bytes = new byte[1024];datagramPacket = new DatagramPacket(bytes, bytes.length);datagramSocket.receive(datagramPacket);byte[] data = datagramPacket.getData();String string = new String(data, 0, datagramPacket.getLength());udpFrame.getTextArea().append("[" + sender + "] : " + string + "\n");Thread.sleep(1000);}} catch (Exception e) {e.printStackTrace();udpFrame.getTextArea().append(sender + "异常\n");udpFrame.getTextArea().append(sender + "与客户端连接中断\n");} finally {udpFrame.getTextArea().append(sender + "关闭\n");}}}

6.ReminderTextAdapter(参考别人的,非原创)

代码如下:

package udpCommunication;import javax.swing.*;import java.awt.*;import java.awt.event.FocusAdapter;import java.awt.event.FocusEvent;public class ReminderTextAdapter extends FocusAdapter {//JTextField提示文字通用方法JTextField textField;String reminderString;//初始化public ReminderTextAdapter(JTextField textField, String reminderString) {this.textField = textField;this.reminderString = reminderString;}//焦点获得@Overridepublic void focusGained(FocusEvent e) {String tempString = textField.getText();//String tempString = this.getText();if (tempString.equals(reminderString)) {textField.setText("");textField.setForeground(Color.BLACK);}}//焦点失去@Overridepublic void focusLost(FocusEvent e) {String tempString = textField.getText();if (tempString.equals("")) {textField.setForeground(Color.GRAY);textField.setText(reminderString);}}}

总结

该项目简单的实现了UDP客户端和服务器端的通信,但是功能比较简单,页面也比较简洁,没有实现多个客户端互聊的功能等,还有待完善。


刚开始写博客,大家觉得不错的点个赞吧!如果大家有什么建议或者问题的,欢迎评论,我会尽量与大家探讨问题的。

如果觉得《Java实现简易UDP客户端 服务器端通信程序》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。