我正在制作一个TFTP应用程序。根据RFC协议,所有数据必须以最大大小为512字节的块的形式发送。因此每个分组可以是<= 512字节。
奇怪的是,对于UDP协议,每次高达3mb的传输都没有大的损失。唯一可能发生的损失是当文件的最后一个块被读取时小于512个字节。
private void sendData() throws Exception
{
DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
InputStream fis = new FileInputStream(responseData);
int a;
while((a = fis.read(outgoingData,0,512)) != -1)
{
serverSocket.send(data);
Thread.sleep(5);
}
}由于这是一个关于读取文件的问题,我如何修复文件末尾的丢失以及无法读取小于512的文件的问题
客户端:
private void receiveData() throws Exception
{
DatagramPacket receiveData = new DatagramPacket(incomingData, incomingData.length);
OutputStream fos = new FileOutputStream(new File("1"+data));
while(true)
{
clientSocket.receive(receiveData);
if(receiveData.getLength() == 512)
{
fos.write(incomingData);xx
} else {
fos.write(incomingData);
fos.close();
break;
}
}
clientSocket.close();
}发布于 2012-03-07 08:10:53
您的数据包(data)具有固定长度的outgoingData.length (512?)现在就来。因此,当您调用serverSocket.send(data)时,它会发送outgoingData数组中的所有数据。
问题是fis.read(outgoingData, 0, 512)有时读取的数据少于512字节。这很可能发生在文件输入流的末尾,此时根本没有那么多数据可供读取。但它也可能发生得更早(在实践中不太可能,但您仍然应该检查以确保安全)。
您已经在a中存储了实际读取的字节数。只需将这个数字传递给setLength,这样DatagramSocket就会知道只发送这么多数据。
这应该能起到作用:
private void sendData() throws Exception
{
DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
InputStream fis = new FileInputStream(responseData);
int a;
while((a = fis.read(outgoingData,0,512)) != -1)
{
data.setLength(a);
// or this
//data = new DatagramPacket(outgoingData, a, clientAddress, clientPort);
serverSocket.send(data);
Thread.sleep(5);
}
}接收:
private void receiveData() throws Exception {
DatagramPacket receiveData = new DatagramPacket(new byte[512], 512);
OutputStream fos = new FileOutputStream(new File("1"+data));
while (true) {
clientSocket.receive(receiveData);
if (receiveData.getLength() == 512) {
fos.write(receiveData.getData());
} else {
fos.write(receiveData.getData(), receiveData.getOffset(), receiveData.getLength());
break;
}
}
fos.close();
clientSocket.close();
}发布于 2012-03-07 08:23:35
private void sendData() throws Exception
{
DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
InputStream fis = new FileInputStream(responseData);
int a;
while((a = fis.read(outgoingData,0,512)) != -1)
{
data.setLength(a); //'a' is the number of bytes read setLength(int) lets you set the length of bytes you want to sent
serverSocket.send(data);
Thread.sleep(5);
}
}setLength(int) Method DatagramPacket现在在接收端,你可以这样做:
byte[]buffer = new byte[512];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
while(socket.isBound() && !socket.isClosed()){
socket.receive(packet);
system.out.println("Packet Length: "+packet.getLength());
//code here
}修复: Server.java中的
private void sendResponse(String res) throws Exception
{
if(res.equals("Y"))
{
// Send ACK -> Send File
DatagramPacket x = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
serverSocket.send(x); //<<SEND ACK
sendData();
} else {
String error = "ERROR: The file you requested does not exist.";
outgoingData = error.getBytes();
DatagramPacket err = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
serverSocket.send(err);
}
}我注意到你没有发送ack,而客户正在期待它,这似乎是你唯一的问题。第一个包目前对您没有任何帮助。现在,您只需将ack包设置为您想要的。我只是在它不包含字符串"ERROR“的时候发送了它。
https://stackoverflow.com/questions/9593886
复制相似问题