ios udp java服务器_Java实现简易UDP客户端、服务器端通信程序

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

效果展示

6291f6ed2584

初始界面

6291f6ed2584

连接成功

6291f6ed2584

互发消息

以下是具体实现过程:

一、项目结构

6291f6ed2584

项目结构

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

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 java.net.DatagramPacket;

import java.net.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:8887

int 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();

}

//向服务器端发送数据

@Override

public void actionPerformed(ActionEvent e) {

//String send = UDPClientFrame.getSendField().getText();

//port:8888

//发送消息

new UDPSend(datagramSocket, clientFrame, "客户端").sendMessages();

}

//使用线程处理客户端接收服务器端的数据

@Override

public 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 java.net.*;

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:8888

serverFrame.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();

}

//向客户端发送数据

@Override

public void actionPerformed(ActionEvent e) {

new UDPSend(datagramSocket, serverFrame, "服务器端").sendMessages();

}

//使用线程处理服务器端接收客户端的数据

@Override

public 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);

//创建JLabel

JLabel 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 java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.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 java.net.DatagramPacket;

import java.net.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;

}

//焦点获得

@Override

public void focusGained(FocusEvent e) {

String tempString = textField.getText();

//String tempString = this.getText();

if (tempString.equals(reminderString)) {

textField.setText("");

textField.setForeground(Color.BLACK);

}

}

//焦点失去

@Override

public void focusLost(FocusEvent e) {

String tempString = textField.getText();

if (tempString.equals("")) {

textField.setForeground(Color.GRAY);

textField.setText(reminderString);

}

}

}

总结

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值