阅读之前,你已经了解了UDP的相关知识;
UDP数据传输时,数据包的大小是有限制的65535, 大概是64k的内容
当数据太大时,需要分包机制,后续补充…如果你有更好的分包方法,请分享给我~谢谢!
接收端的代码:
public class UdpServerThread2 extends Thread {
public static final PrintStream p = System.out;
private static final int DATA_LEN = 1228800;
public static String serverIp = "192.168.124.78";
public static int serverPort = 8089;
private static Object lock = new Object();
private final SaveFileThread fileThread;
byte[] data;
DatagramSocket socket;
private boolean isExit = false;
private UdpServerThread2() throws SocketException {
//创建一个 socket,监听 serverPort端口
socket = new DatagramSocket(serverPort);
//创建一个保存数据到文件的线程,非必须
fileThread = new SaveFileThread();
fileThread.start();
}
//启动方法
public static void main(String... args) {
try {
new UdpServerThread2().start();
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (!isExit) {
data = new byte[DATA_LEN];
//创建一个用于接收数据的数据包对象,需要指定长度
DatagramPacket packet = new DatagramPacket(data, DATA_LEN);
try {
p.println("等待中...");
//等待接收数据...
socket.receive(packet);
// String s = new String(data);
// p.println("收到数据包:" + s + " 大小:" + packet.getLength() + " 字节" + " 长度:" + s.length());
p.println("收到数据包大小:" + packet.getLength() + " 字节");
//将数据保存到文件
fileThread.saveData(data, packet.getLength());
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** * 保存文件的线程 */
class SaveFileThread extends Thread {
private Vector<byte[]> saveData;
private volatile int length;
public SaveFileThread() {
this.saveData = new Vector<>();
File png = new File("png");
if (!png.exists()) {
png.mkdirs();
}
}
private String getSaveFileName() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH-mm-ss-SSS");
String format = simpleDateFormat.format(new Date());
return (format + ".png");
}
public void saveData(byte[] data, int len) {
saveData.add(data);
length = len;
}
@Override
public void run() {
while (!isExit) {
if (!saveData.isEmpty()) {
byte[] data = saveData.remove(0);
try {
String fileName = getSaveFileName();
FileOutputStream outputStream = new FileOutputStream(new File("png" + File.separator + fileName));
outputStream.write(data, 0, length);
outputStream.close();
p.println("保存至:-->" + fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
发送端的代码
public class UdpSendThread extends Thread {
private static Object lock = new Object();
private static UdpSendThread sendThread;
private volatile boolean isExit = false;
private Vector<int[]> sendDataInt;
private Vector<byte[]> sendDataByte;
private DatagramSocket socket;
private int port = 8089;
private String ip = "192.168.124.78";
private UdpSendThread() {
sendDataInt = new Vector<>();
sendDataByte = new Vector<>();
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
}
public static UdpSendThread getInstance() {
if (sendThread == null) {
synchronized (lock) {
if (sendThread == null) {
sendThread = new UdpSendThread();
sendThread.start();
}
}
}
return sendThread;
}
/** * 将int数值转换为占四个字节的byte数组,本方法适用于(低位在前,高位在后)的顺序。 和bytesToInt()配套使用 * * @param value 要转换的int值 * @return byte数组 */
public static byte[] intToBytes(int value) {
byte[] src = new byte[4];
src[3] = (byte) ((value >> 24) & 0xFF);
src[2] = (byte) ((value >> 16) & 0xFF);
src[1] = (byte) ((value >> 8) & 0xFF);
src[0] = (byte) (value & 0xFF);
return src;
}
/** * byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序,和和intToBytes()配套使用 * * @param src byte数组 * @param offset 从数组的第offset位开始 * @return int数值 */
public static int bytesToInt(byte[] src, int offset) {
int value;
value = (int) ((src[offset] & 0xFF)
| ((src[offset + 1] & 0xFF) << 8)
| ((src[offset + 2] & 0xFF) << 16)
| ((src[offset + 3] & 0xFF) << 24));
return value;
}
public static byte[] intsToBytes(int[] values) {
byte[] src = new byte[4 * values.length];
for (int i = 0; i < values.length; i++) {
byte[] bytes = intToBytes(values[i]);
for (int j = 0; j < bytes.length; j++) {
src[i * 4 + j] = bytes[j];
}
// System.arraycopy(bytes, 0, src, i * 4, bytes.length);
}
return src;
}
public void send(int[] data) {
try {
//数据类型的转换
byte[] bytes = intsToBytes(data);
//创建一个数据包,包含数据,端口,目标地址
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
packet.setPort(port);
packet.setAddress(InetAddress.getByName(ip));
//发送...
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(byte[] data) {
sendDataByte.add(data);
}
public void exit() {
isExit = true;
}
@Override
public void run() {
while (!isExit) {
// if (!sendDataInt.isEmpty()) {
// int[] data = sendDataInt.remove(0);
//
// }
if (!sendDataByte.isEmpty()) {
try {
byte[] data = sendDataByte.remove(0);
DatagramPacket packet = new DatagramPacket(data, data.length);
packet.setPort(port);
packet.setAddress(InetAddress.getByName(ip));
socket.send(packet);
System.out.println("发送数据长度:" + data.length + "字节");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.