【发布时间】:2018-10-12 14:58:23
【问题描述】:
使用 Java,我试图通过 DatagramSocket 发送一些文件数据。我需要以 1000 字节的块读取文件并将它们作为数据包发送。我的代码:
- 将文件读入字节缓冲区中包装的字节数组中
- 将数据放入数据包并发送
- 让接收方打开数据包并将内容重新写入新文件。
我在将字节数组写回文件时遇到问题。请在下面查看我的代码。
客户/发件人:
byte[] data = new byte[1000];
ByteBuffer b = ByteBuffer.wrap(data);
DatagramPacket pkt;
File file = new File(sourceFile);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
CRC32 crc = new CRC32();
while(true){
b.clear();
b.putLong(0); // I need to put the checksum at the beginning for easy retrieval
bytesRead = bis.read(data);
if(bytesRead==-1) { break; }
crc.reset();
crc.update(data, 8, data.length-8);
long chksum = crc.getValue();
b.rewind();
b.putLong(chksum);
pkt = new DatagramPacket(data, 1000, addr); // addr is valid, works fine
sk.send(pkt);
}
bis.close();
fis.close();
服务器/接收器:
DatagramSocket sk = new DatagramSocket(port);
File destfile = new File("hello.txt");
FileOutputStream fos = new FileOutputStream(destfile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
PrintStream ps = new PrintStream(fos);
byte[] data = new byte[1000];
DatagramPacket pkt = new DatagramPacket(data, data.length);
ByteBuffer b = ByteBuffer.wrap(data);
CRC32 crc = new CRC32();
while(true) {
pkt.setLength(data.length);
sk.receive(pkt);
b.rewind();
// compare checksum, print error if checksum is different
// if checksum is the same:
bos.write(data); // Where the problem seems to be occurring.
// send acknowledgement packet.
}
bos.close();
fos.close();
在这里,我主要是在写回文件时遇到问题。使用一个写着Hello World! 的小文本文件,我得到一个奇怪的输出,写着vˇ]rld!。另外,输入文件只有 12 个字节,但接收方创建的文件是 1KB。
我认为我的问题是处理字节缓冲区 - 我编写了一个使用文件流和缓冲流复制文件的程序,效果很好。但是我对流在这种情况下的工作方式感到困惑,我非常感谢任何帮助。谢谢!
【问题讨论】:
-
问题:为什么选择 UDP 而不是 TCP?鉴于您是,您确定 1,000 字节的卡盘有意义并且可以独立处理吗?
-
@ControlAltDel 关于协议和块大小的选择,不幸的是,这是一个给定的约束。我必须使用 UDP 并创建最大 1000 字节的数据包。
-
您的文件为 1KB 是有道理的,因为您发送了一个 1000 字节的数据包。
-
我没有测试过,但是你可能应该根据ByteBuffer的位置来设置数据包长度。
-
@aglassman 是的,你在两个方面都是对的 - 谢谢!我已经相应地编辑了我的代码,现在效果很好。 :D
标签: java