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

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

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

}
}

java udp服务器设计源码的更多相关文章

  1. Java开源生鲜电商平台-用户表的设计(源码可下载)

    Java开源生鲜电商平台-用户表的设计(源码可下载) 说明:由于该系统属于B2B平台,不设计到B2C的架构. 角色分析:买家与卖家. 由于买家与卖家所填写的资料都不一样,需要建立两站表进行维护,比如: ...

  2. Java开源生鲜电商平台-商品表的设计(源码可下载)

    Java开源生鲜电商平台-商品表的设计(源码可下载) 任何一个电商,无论是B2C还是B2B的电商,商品表的设计关系到整个系统架构的核心. 1. 商品基本信息表:用单词:goods做为商品表 2. 商品 ...

  3. Java开源生鲜电商平台-订单表的设计(源码可下载)

    Java开源生鲜电商平台-订单表的设计(源码可下载) 场景分析说明: 买家(餐馆)用户,通过APP进行选菜,放入购物车,然后下单,最终支付的流程,我们称为下单过程. 买家可以在张三家买茄子,李四家买萝 ...

  4. 死磕 java集合之CopyOnWriteArraySet源码分析——内含巧妙设计

    问题 (1)CopyOnWriteArraySet是用Map实现的吗? (2)CopyOnWriteArraySet是有序的吗? (3)CopyOnWriteArraySet是并发安全的吗? (4)C ...

  5. JAVA上百实例源码以及开源项目

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...

  6. JAVA上百实例源码网站

    JAVA源码包1JAVA源码包2JAVA源码包3JAVA源码包4 JAVA开源包1 JAVA开源包2 JAVA开源包3 JAVA开源包4 JAVA开源包5 JAVA开源包6 JAVA开源包7 JAVA ...

  7. java 并发编程——Thread 源码重新学习

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  8. Java汽车租赁系统[源码+数据库]

    系统名称 Java汽车租赁系统   (源码在文末) 系统概要 汽车租赁系统总共分为两个大的模块,分别是系统模块和业务模块.其中系统模块和业务模块底下又有其子模块. 功能模块 一.业务模块 1.客户管理 ...

  9. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...

随机推荐

  1. sendemail 发送成功Email was sent successfully!邮箱却收不到邮件

    在测试sendemail的时候,发现好多次明明提示已经发送成功了,但是邮箱却一直收不到邮件. 查询了好多资料,主要原因有两个 1.如果Linux是sentos的话,主要是防火墙iptables和sel ...

  2. 在Linux下的找不同-打补丁

    Q:为什么要找不同,为什么要打补丁? A: 在Linux应用中,作为DBA,我们知道MySQL跑在Linux系统之上,数据库最重要的追求就是性能,"稳"是重中之重,所以不能动不动就 ...

  3. 终端的CTRL+S 解说

    在很多类Unix 的系统上,Ctrl-S 都有特殊的含义:它会"冻结"终端(它曾 经被用来暂停快速滚动).因为"保存"一般也是用这个快捷键,所以经常 会有人不假 ...

  4. 小程序的1024KB

    1024kb 只是一个目前编译后代码可上传最大限制,至于后期会不会更改,不得而知.个人只是想借 1024kb 来和大家一起交流一下,如何在限制下,挥舞大刀- 微信官方回答了,为什么有 1024kb 的 ...

  5. 谈一谈JDK8的函数式编程 (一)

    系列之前我想说的   最近有一段时间没写博客了,这几天回到学校,才闲下来,决定写一写最近学习到的只是,既是为了分享,也是为了巩固.之前看到过一篇调查,文章的数据是学习新知识,光是看只能获得大约5%,然 ...

  6. 1254 Flip and Shift

    这题是目的是把黑球和白球分开连续放,事实上只要把其中一种颜色分好在一边就可以,可以绕一个球转即是第n个球可以放在n-2或者n+2上,因为这是个环,所以只需要把黑球或者白球连续放好就可以,当一共有奇数个 ...

  7. 关于jQuery表单选择中prop和attr的区别。

    今天用jQuery学习表单这一章节的内容,再次遇到表单全选时,不能进行第二次全选的情况.反复查看测试仍然找不到是什么原因.后来在网上查到原来是jQuery1.6以后的版本用到的是prop.用attr的 ...

  8. Building [Security] Dashboards w/R & Shiny + shinydashboard(转)

    Jay & I cover dashboards in Chapter 10 of Data-Driven Security (the book) but have barely mentio ...

  9. Android学习探索之App多渠道打包及动态添加修改资源属性

    前言: 关于Android渠道打包是一个比较老的话题,今天主要记录总结一下多渠道打包以及如果动态配置修改一些资源属性.今天以公司实际需求为例进行演示,由于项目复用很多公共的业务组件,而且业务组件之间的 ...

  10. 【Android】又一个Gank客户端来啦

    介绍 Gank平台的移动端又来了,非常感谢Gank平台开放接口,让我们这些小白有机会练手.学习. 本项目在架构方面有稍微花点心思,虽然还是最简单的MVC模式,但基本参考MVP的思想,Activity只 ...