java udp服务器设计源码

根据个人理解写的,轻喷。

没什么大的逻辑,直接上代码。

UDPServer.java

package mySocket;
/*
* 服务器端
*/
import java.awt.GridLayout;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class UDPServer extends JFrame{
static JTextArea textArea;
JPanel panel;
static Vector<String> list = new Vector<String>();
public UDPServer(){
this.setTitle("服务器端");
this.setLocation(100,100);
this.setSize(1100, 600);

this.setLayout(null);

this.setLayout(new GridLayout(1,2));
textArea = new JTextArea();
panel = new JPanel();

panel.setLayout(null);
textArea.setSize(this.getWidth()/2, this.getHeight());
panel.setSize(this.getWidth()/2, this.getHeight());
textArea.setEditable(false);
this.add(new JScrollPane(textArea));
this.add(panel);

this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
UDPServer UDPserver = new UDPServer();
textArea.append("***************************服务器已启动,"
+ "等待客户端的接入***************************\n");
try {
DatagramSocket server = new DatagramSocket(8888);
while (true) {
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
server.receive(packet);
UDPServerThread st = new UDPServerThread(server,bytes,packet,UDPserver,list);
st.start();
}

} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

UDPClient.java

package mySocket;
/*
* 客户端
*/
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class UDPClient extends JFrame implements ActionListener{
static JTextArea textArea;
String username;
JPanel panel;
JTextField sendTextfield;
JButton button;
DatagramSocket client;
InetAddress address;
int port;
Date date;
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time;
public UDPClient(String username) throws Exception{
this.username = username;

this.setTitle("客户端");
this.setLocation(300,100);
this.setSize(400, 600);

panel = new JPanel();
textArea = new JTextArea();
sendTextfield = new JTextField(20);
button = new JButton("发送");

this.setLayout(new GridLayout(2, 1));
panel.setLayout(null);
textArea.setEditable(false);
sendTextfield.setBounds(0, 0, 200, 40);
button.setBounds(220, 0, 50, 40);
sendTextfield.setFocusable(true);

this.add(new JScrollPane(textArea));
panel.add(sendTextfield);
panel.add(button);
this.add(panel);

button.addActionListener(this);

this.setResizable(false);
this.setVisible(true);

this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
date = new Date();
time = format.format(date);
byte[] data = ("-"+username).getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
try {
client.send(packet);
} catch (IOException e1) {
e1.printStackTrace();
}
}

});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client();
}

public void client() throws Exception{
/*
* 向服务器端发送数据
*/
// 1.定义服务器的地址,端口号,数据
address = InetAddress.getByName("localhost");
port = 8888;
date = new Date();
time = format.format(date);
client = new DatagramSocket();
byte[] data = ("用户 "+username+" 已加入(IP地址:"+address.toString()+";端口号:"+client.getLocalPort()+";时间:"+time+")").getBytes();
// 2.创建数据报,包含了发送的信息
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
// 3.创建 DatagramSocket

// 4.向服务器端发送数据
client.send(packet);

byte[] bytes = new byte[1024];
UDPClientThread st = new UDPClientThread(client,bytes,packet,this);
st.start();
}

public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
if(btn==button){
String sendData = sendTextfield.getText();
sendTextfield.setText("");
if(!sendData.equals("")){
date = new Date();
time = format.format(date);
String CRCsendData = Arrays.toString(CRCCheck.getCRCByteValue(sendData.getBytes()));
byte[] data = ("^"+CRCsendData+"*"+username+"_"+sendData).getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
try {
client.send(packet);
byte[] bytes = new byte[1024];
packet = new DatagramPacket(bytes, bytes.length);
// 2.接收服务器响应的数据
client.receive(packet);
// 3.读取数据
String reply = new String(bytes, 0, packet.getLength());
if(reply.equals("00000000")){
textArea.append("数据发送失败,请重新发送\n");
}else{
String username = reply.substring(0,reply.indexOf("_"));
String content = reply.substring(reply.indexOf("_")+1,reply.length());
textArea.append("用户 "+username+" 说:"+content+"\n");
}

} catch (IOException e1) {
e1.printStackTrace();

}
}
}
}
}

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { text-decoration: underline }

UDPServerThread.java

package mySocket;
/*
* 服务器端线程
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.JList;

public class UDPServerThread extends Thread {
DatagramSocket socket;
byte[] bytes;
DatagramPacket packet;
String info;
UDPServer UDPserver;
Vector<String> list;

public UDPServerThread(DatagramSocket socket, byte[] bytes, DatagramPacket packet, UDPServer uDPserver, Vector<String> list) {
this.socket = socket;
this.bytes = bytes;
this.packet = packet;
this.UDPserver = uDPserver;
this.list = list;
}
public void run() {
// 创建数据报,用于接收客户端发送的数据

try {
String sendData = null,username;
boolean isresponse = false;
// 读取数据
info = new String(bytes, 0, packet.getLength());
if(info.substring(0, 1).equals("-")){
username = info.substring(1);
list.remove(username);
UDPserver.textArea.append("用户 "+username+" 已断开连接\n");
}
else if(info.substring(0, 1).equals("^")){
isresponse = true;
String CRCinfo = info.substring(info.indexOf("^")+1,info.indexOf("*"));
String infoContent = info.substring(1).substring(info.indexOf("_"),info.length()-1);
String CRCcontent = Arrays.toString(CRCCheck.getCRCByteValue(infoContent.getBytes()));
UDPserver.textArea.append("客户端CRC校验码:"+CRCinfo+"\n");
UDPserver.textArea.append("服务器端CRC校验码:"+CRCcontent+"\n");
if(CRCinfo.equals(CRCcontent)){
UDPserver.textArea.append("匹配成功\n");
UDPserver.textArea.append(">>>>>用户 "+info.substring(info.indexOf("*")+1,info.indexOf("_"))+" 发送了一个数据包,内容为:"+infoContent+"\n\n");
sendData = info.substring(info.indexOf("*")+1,info.indexOf("_"))+"_"+info.substring(1).substring(info.indexOf("_"),info.length()-1);
}else{
UDPserver.textArea.append("匹配失败\n");
sendData = "00000000";
}

}else{
isresponse = true;
username = info.substring(info.indexOf("户")+2, info.indexOf("已")-1);
list.add(username);
UDPserver.textArea.append(info+"\n");
sendData = "欢迎 "+info.substring(info.indexOf("户")+2, info.indexOf("已")-1)+" 加入";
}

UDPserver.panel.removeAll();
JList<Object> lists = new JList<Object>(list);
lists.setBounds(0, 0, 550, 600);
UDPserver.panel.add(lists);
UDPserver.panel.updateUI();
/*
* 响应客户端发来的消息
*/

// 1.定义客户端的地址,端口号,数据
if(isresponse){
InetAddress address = packet.getAddress();
int port = packet.getPort();

byte[] data = sendData.getBytes();
// 2.创建数据报,包含响应的数据信息
packet = new DatagramPacket(data, data.length, address, port);
// 3.响应客户端,发送数据
socket.send(packet);
}

} catch (IOException e) {
e.printStackTrace();
}

}
}

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }

UDPClientThread.java

package mySocket;
/*
* 客户端线程类
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPClientThread extends Thread{
DatagramSocket client;
byte[] bytes;
DatagramPacket packet;
UDPClient udpClient;
public UDPClientThread(DatagramSocket client, byte[] bytes, DatagramPacket packet, UDPClient udpClient){
this.client = client;
this.bytes = bytes;
this.packet = packet;
this.udpClient = udpClient;
}
public void run(){
try {
packet = new DatagramPacket(bytes, bytes.length);
client.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String reply = new String(bytes, 0, packet.getLength());
if(!reply.equals(""))
udpClient.textArea.append(reply+"\n");
}
}

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }

CRCCheck.java

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #4f76cb }
p.p4 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #91afcb }
p.p5 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #931a68 }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }
span.s3 { color: #0326cc }
span.s4 { color: #3933ff }
span.s5 { color: #000000 }
span.s6 { color: #91afcb }
span.s7 { color: #4f76cb }
span.Apple-tab-span { white-space: pre }

package mySocket;

import java.util.Arrays;

public class CRCCheck {

public static void main(String[] args) {

byte[] btm = new byte[] { 12, 13, 1, 0, 0, 1, 0, 31, -19, 0, 8,

0, 1 };

byte[] btl = CRCCheck.getCRCByteValue(btm);

System.out.println(Arrays.toString(btl));

byte[] testbyte = CRCCheck.getCRCByteValue("哈哈".getBytes());

byte[] testbyte2 = CRCCheck.getCRCByteValue("哈哈".getBytes());

System.out.println(Arrays.toString(testbyte));

System.out.println(Arrays.toString(testbyte2));

}

/**

* 入口方法

* @param bt 需要校验的字节流

* @return

*/

public static byte[] getCRCByteValue(byte[] bt){

char ch = caluCRC(bt);

return charToByte(ch);

}

public static char[] crc_tb = {

0x0000, 0x1021, 0x2042, 0x3063, 0x4084,

0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c,

0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5,

0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd,

0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6,

0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,

0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7,

0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df,

0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840,

0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948,

0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71,

0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79,

0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22,

0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a,

0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,

0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b,

0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c,

0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004,

0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d,

0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235,

0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e,

0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466,

0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f,

0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,

0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8,

0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0,

0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9,

0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1,

0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa,

0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2,

0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b,

0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93,

0x3eb2, 0x0ed1, 0x1ef0

};

/**

* 获得CRC验证码

*/

public static char caluCRC(byte[] pByte) {

int len = pByte.length;

char crc;

byte da;

crc = 0x0;

int i = 0;

while (len-- != 0) {

da = (byte) (crc / 256);

crc <<= 8;

int num = da ^ pByte[i];

if (num < 0)

num += 256;

crc ^= crc_tb[num];

++i;

}

return crc;

}

/**

* char 转byte

*/

public static byte[] charToByte(char c) {

byte[] b = new byte[2];

b[0] = (byte) ((c & 0xFF00) >> 8);

b[1] = (byte) (c & 0xFF);

return b;

}

}

/*用户登录界面,服务器运行状态下执行,客户端的main方法就在这个类里*/

User.java

package mySocket;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/*
* 用户接入窗口类
*/
public class User extends JFrame implements ActionListener{
JPanel mainPanel;
JLabel userLabel,tipLabel;
JTextField userTextfield;
JButton loginBtn;
public User(){
this.setTitle("用户登录");
this.setLocation(300,100);
this.setSize(550, 600);

mainPanel = new JPanel();
userLabel = new JLabel("YourName:");
tipLabel = new JLabel("");
userTextfield = new JTextField(10);
loginBtn = new JButton("登入");

mainPanel.setBounds(0, 0, this.getWidth(), this.getHeight());
mainPanel.setLayout(null);
userLabel.setBounds(100, 200, 100, 20);
userTextfield.setBounds(210, 195, 150, 30);
tipLabel.setBounds(360, 200, 150, 20);
tipLabel.setForeground(Color.red);
loginBtn.setBounds(150, 250, 100, 20);

mainPanel.add(userLabel);
mainPanel.add(userTextfield);
mainPanel.add(tipLabel);
mainPanel.add(loginBtn);
this.add(mainPanel);

loginBtn.addActionListener(this);

this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
User user = new User();
}
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
if(btn==loginBtn){
String username = userTextfield.getText();
if(username.equals("")){
tipLabel.setText("请输入一个名称!");
}else{
this.dispose();
try {
new UDPClient(username);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}

}
}

上一篇:【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能


下一篇:redis的发布订阅、持久化存储、redis的主从复制