java udp服务器设计源码
Posted 寻梦1314
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
}
}
}
}
}
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();
}
}
}
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");
}
}
CRCCheck.java
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();
}
}
}
}
}
以上是关于java udp服务器设计源码的主要内容,如果未能解决你的问题,请参考以下文章
20165327 2017-2018-2 《Java程序设计》第9周学习总结