当前位置: 首页 > news >正文

各大网站注册记录找人做网站排名优化

各大网站注册记录,找人做网站排名优化,一般的域名可以做彩票网站吗,提升学历哪种方式含金量高任务要求 试完善文件传输功能,可选择 1.使用基于TCP的Socket进行改写;2.优化基于UDP文件传输,包括有序发送、接收端细粒度校验和发送端数据重传。 这里我们来进行UDP的优化 首先我们知道的是在传输大量数据时,UDP协议的传输容易…

任务要求

试完善文件传输功能,可选择 1.使用基于TCP的Socket进行改写;2.优化基于UDP文件传输,包括有序发送、接收端细粒度校验和发送端数据重传。

这里我们来进行UDP的优化

首先我们知道的是在传输大量数据时,UDP协议的传输容易出现数据的缺失(这里我们可以采用计算文件的MD5值来进行验证),因此我们需要进行优化,优化的点为有序发送、接收端细粒度校验和发送端数据重传。

为了完成上述优化,我们需要对发送的数据包进行一定地封装,这里我采用以下方案

1.每次传输的数据包大小为512bytes

2.前8位存储两个整型,分别时数据包编号(即第几个数据包),还有传输内容的长度(不包括修饰的前缀)

3.接下来34位存储MD5码,理论来说计算得到的MD5码应该为32位,但是笔者这里采用的写入字符串的方式来打包入数据包,这导致MD5占了34位,具体原因还未搞清楚,可能是因为前两位是用于标记16进制的,但是无妨,不影响我们后续的进行

在修改接收器和发送器的代码前,我们需要对于MD5工具类进行修改,使其可以对于byte[]型的数据进行计算

import java.security.MessageDigest;public class MD5Util_byte {public static String getMD5(byte[] input) {try {MessageDigest MD5 = MessageDigest.getInstance("MD5");byte[] data = input;MD5.update(data);return new String(byte2hex(MD5.digest()));} catch (Exception e) {e.printStackTrace();return null;}}private static String byte2hex(byte[] b) {String hs = "";String stmp = "";for (int n = 0; n < b.length; n++) {stmp = (java.lang.Integer.toHexString(b[n] & 0xFF));if (stmp.length() == 1)hs = hs + "0" + stmp;elsehs = hs + stmp;}return hs;}
}

这样我们就可以利用MD5Util_byte.getMD5()来计算MD5值了。

 

接下来我们需要完成UDPFileSender

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.Arrays;
import java.util.Random;
public class UDPFileSender {public static void main(String[] args) throws IOException, NoSuchAlgorithmException {// 生成并写入发送文件try (FileWriter fileWriter = new FileWriter("checksum.txt")) {Random r = new Random(2023);// 尝试 1e3 and 1e8for (int i = 0; i < 1e8; i++) {fileWriter.write(r.nextInt());}}File file = new File("checksum.txt");System.out.println("发送文件生成完毕");System.out.println("发送文件的md5为: " + MD5Util.getMD5(file));FileInputStream fis = new FileInputStream(file);DatagramSocket socket = new DatagramSocket();byte[] bytes = new byte[512-42];DatagramPacket packet;boolean resend = false;int sequenceNumber = 0; // 添加序列号变量// 不断从文件读取字节并将其组装成数据报发送int len;DatagramPacket lastPacket = null;while ((len = fis.read(bytes)) != -1) {if (resend) {// 重新发送上一个数据包socket.send(lastPacket);resend = false; // 重置重新发送标记} else {// 计算校验和String checksum = MD5Util_byte.getMD5(bytes);if (len < 470) {checksum = MD5Util_byte.getMD5(Arrays.copyOfRange(bytes, 0, len));}// 构造带有序列号和校验和的数据包ByteArrayOutputStream baos = new ByteArrayOutputStream();DataOutputStream dos = new DataOutputStream(baos);dos.writeInt(sequenceNumber);dos.writeUTF(checksum);System.out.println(len);dos.writeInt(len);dos.write(bytes, 0, len);dos.flush();byte[] sendData = baos.toByteArray();System.out.println(sendData.length);System.out.println("sendData: " + Arrays.toString(sendData));packet = new DatagramPacket(sendData, sendData.length, InetAddress.getLocalHost(), 9092);socket.send(packet);lastPacket = packet; // 保存上一个数据包,以便在接收方报告错误时重新发送}// 等待接收方的响应DatagramPacket responsePacket = new DatagramPacket(new byte[512], 512);socket.receive(responsePacket);String response = new String(responsePacket.getData(), 0, responsePacket.getLength());// 检查接收方的响应是否表示接收错误,如果是,则重新发送上一个数据包if (response.equals("ERROR")) {System.out.println("接收方报告接收错误,重新发送上一个数据包");resend = true;}else if (response.equals("OK")) {System.out.println("接收方报告接收正确");}else {System.out.println("接收方报告未知错误");resend = true;}sequenceNumber++; // 更新序列号}// 发送终止符byte[] a = new byte[0];System.out.println("flag");packet = new DatagramPacket(a, a.length, InetAddress.getLocalHost(), 9092);socket.send(packet);fis.close();socket.close();System.out.println("向" + packet.getAddress().toString() + "发送文件完毕!端口号为:" + packet.getPort());}
}

可以看到,我们的UDPFileSender首先随机生成数据写入文件,然后从文件不断读入并且按照我们希望的方式对数据进行打包,同时等待接受器的回写消息,若发生错误则重新发送出现错误的数据包。

而UDPFileReceiver也是相同的逻辑

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;public class UDPFileReceiver {public static void main(String[] args) throws IOException {File file = new File("checksum_recv.txt"); //要接收的文件存放路径FileOutputStream output = new FileOutputStream(file);byte[] data = new byte[512];DatagramSocket ds = new DatagramSocket(9092);int len=470;// 使用一个循环来接收数据报,并根据序列号将数据写入文件DatagramPacket dp = new DatagramPacket(data, data.length);while (true) {ds.receive(dp);ByteArrayInputStream bais = new ByteArrayInputStream(dp.getData());DataInputStream dis = new DataInputStream(bais);int sequenceNumber = dis.readInt();if (len!=470) // 收到终止符则退出循环break;byte[] checksum = new byte[34];dis.readFully(checksum);len = dis.readInt();System.out.println("len: " + len);byte[] receivedData = new byte[512-42]; // 数据长度减去序列号和校验和的长度dis.read(receivedData, 0,len);if(len < 470){byte[] temp = new byte[len];System.arraycopy(receivedData, 0, temp, 0, len);receivedData = temp;}// 计算接收到的数据包的校验和String receivedChecksum = MD5Util_byte.getMD5(receivedData);// System.out.println("receivechecksum: " + receivedChecksum);byte[] receivedChecksum_byte = receivedChecksum.getBytes(StandardCharsets.UTF_8);byte[] stantardChecksum = new byte[checksum.length-2];System.arraycopy(checksum, 2, stantardChecksum, 0, checksum.length-2);// 比较校验和if (!Arrays.equals(stantardChecksum, receivedChecksum_byte)){System.out.println("接收到的数据包校验和与发送端不一致,丢弃该数据包!"+ "sequenceNumber: " + sequenceNumber+ " receivedChecksum: " + Arrays.toString(receivedChecksum_byte)+ " checksum: " + Arrays.toString(checksum));// 向发送端报告错误InetAddress senderAddress = dp.getAddress();int senderPort = dp.getPort();String errorMessage = "ERROR"; // 错误消息byte[] errorData = errorMessage.getBytes(StandardCharsets.UTF_8);DatagramPacket errorPacket = new DatagramPacket(errorData, errorData.length, senderAddress, senderPort);ds.send(errorPacket);continue;}InetAddress senderAddress = dp.getAddress();int senderPort = dp.getPort();String errorMessage = "OK"; // 错误消息byte[] errorData = errorMessage.getBytes(StandardCharsets.UTF_8);DatagramPacket errorPacket = new DatagramPacket(errorData, errorData.length, senderAddress, senderPort);ds.send(errorPacket);System.out.println("接收到的数据包校验和与发送端一致,写入文件!"+ "sequenceNumber: " + sequenceNumber);output.write(receivedData); // 将数据写入文件}output.close();ds.close();System.out.println("接收来自" + dp.getAddress().toString() + "的文件已完成!对方所使用的端口号为:" + dp.getPort());file = new File("checksum_recv.txt");System.out.println("接收文件的md5为: " + MD5Util.getMD5(file));}
}

我们需要对接收的数据包进行解析,比对MD5码,最后根据结果选择写入还是向Sender报错。

最后我们进行验证

Receiver

Sender

 

当然我们也可以编写一个小程序来检验文件的完整性

这样我们完成了对于UDP文件传输的优化

 

http://www.yayakq.cn/news/763404/

相关文章:

  • 沈阳网站优化排名活动策划案格式模板和范文
  • 案例应聘网络营销做网站推广单一网页开发
  • 网站建设中 页面源代码宁波男科医院哪家比较好
  • 企业网站建设 详细方案网球新闻最新消息
  • 企业网站建设管理制度作品集展示的网站
  • 企业网站首页应如何布局如何为自己的店铺做网站
  • 销售网站快速建立专业做影楼招聘网站有哪些
  • 中端网站建设wordpress黑镜百度云盘
  • 建立网站的第一步知名的定制网站建设提供商
  • 百度商桥要怎么添加到网站常用的网站建设技术
  • 建设银行纪检监察网站西部数据wordpress
  • 农业综合管理网站建设广州站有高铁吗
  • 能发朋友圈的网站建设广告语张家界做网站找哪家好
  • 微网站 模板wordpress 有图片的文章
  • 成都成仁路网站建设查备案网站备案
  • 网站设计制作从哪里学起东莞企业网站教程
  • 网站做编辑网站设计如何收费标准
  • 深圳罗湖区住房和建设局网站怎样建设网站的步骤
  • 怎么创建网站挣钱wordpress 扁平化主题
  • 和县网站设计怎么自己弄一个网站
  • 网页网站建设商场设计方案ppt
  • 做提升自己的网站制作网页的最后一个阶段工作是什么
  • 经济研究院网站建设方案网页设计类型与风格
  • 母婴网站怎么做河北雄安新区规划建设局网站
  • 临沂网站建设价格下载学校网站模板
  • 自助建站软件微信公众号和小程序哪个好
  • 专做宝宝辅食的网站杭州科技学校网站建设
  • 响水做网站wordpress禁用xmlrpc
  • 长沙设计网站效果软件开发流程八个步骤概要分析
  • 做庭院的网站广东建设教育协会网站