gpt4 book ai didi

java - 从 UDP 服务器发送文件时出现问题

转载 作者:行者123 更新时间:2023-12-01 17:37:03 25 4
gpt4 key购买 nike

我正在用 Java 编写一个小型 UDP 服务器。当服务器收到命令('GET_VIDEO')时,他读取文件('video.raw'),然后将其发送到客户端。我的问题是从服务器发送的字节数不等于客户端接收的字节数,并且我的测试失败。这是服务器代码:

public class ServerMock {

public static void main(String[] args) throws Exception {

byte[] buff = new byte[64];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
DatagramSocket socket = new DatagramSocket(8080);

System.out.println("Server started at 8080 ...");

while (true) {
socket.receive(packet);
new ServerMock.ThreadVideo(socket, packet).run();

}
}

public static class ThreadVideo implements Runnable {

private DatagramPacket packet;
private DatagramSocket socket;

public ThreadVideo(DatagramSocket socket, DatagramPacket packet) {
this.packet = packet;
this.socket = socket;
}

public void run() {
String cmd = new String(packet.getData(), 0, packet.getLength());
if (cmd.equals("GET_VIDEO")) {
try {
read_and_send_video(this.packet.getAddress());
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("S:Exiting ....");
System.exit(0);
}
}


private void read_and_send_video(InetAddress address)
throws IOException {

File file = new File("./video/video.raw");
FileInputStream fis = new FileInputStream(file);
DatagramPacket pack;

int size = 0;
byte[] buffer = new byte[64000];
ByteBuffer bb = ByteBuffer.allocate(4);
bb.order(ByteOrder.BIG_ENDIAN);

while (true) {
size = fis.read(buffer);
System.out.println("Size = " + size);

// Envoi du contenu du fichier
pack = new DatagramPacket(buffer, buffer.length, address,
packet.getPort());
socket.send(pack);
if (size == -1) {
break;
}
}

String cmd = "END_VIDEO";
pack = new DatagramPacket(cmd.getBytes(), cmd.getBytes().length,
address, packet.getPort());
socket.send(pack);

}

}

}

这是我的客户端代码:

public void client(int timeout, String message)
throws SocketTimeoutException, SocketException {

try {

File file = new File("./video/tmp.raw");
FileOutputStream fos = new FileOutputStream(file);
File filein = new File("./video/video.raw");

InetAddress address = InetAddress.getByName(host);
byte[] data = message.getBytes();
byte[] buffer = new byte[64000];

DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(timeout);

DatagramPacket packet = new DatagramPacket(data, data.length,
address, port);
socket.send(packet);

DatagramPacket rpacket = new DatagramPacket(buffer, buffer.length);

while (true) {
socket.receive(rpacket);
if (rpacket.getLength() <= 9) {
String cmd = new String(rpacket.getData(), 0,
rpacket.getLength());
if (cmd.equals("END_VIDEO")) {
System.out.println("C:Fin de transmission");
break;
}
}
fos.write(rpacket.getData());
}

System.out.println("video.raw ->" + filein.length());
System.out.println("tmp.raw -> " + file.length());
Assert.assertTrue(file.length() == filein.length());

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnknownHostException e) {

e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

任何人都可以帮我解决这个问题。一些 friend 建议我使用 ByteBuffer、ByteOrder 类,但我不知道如何使用它们,因为我不知道服务器读取文件时实际读取了多少字节。实现这一目标的最佳方法是什么

谢谢

最佳答案

UDP 是不可靠的,无法保证您会收到所有发送的 UDP 数据包,或者您会按照发送的顺序收到它们。您将需要用序列号标记每个数据包,您将需要在客户端上对它们重新排序,您将需要告诉服务器何时放慢速度(或实现确认机制),您将需要能够请求重传.

简而言之,除非客户端对丢失和无序的数据包感到满意(就像大多数流媒体客户端一样),否则您将需要重新实现基于 UDP 的 TCP,或者仅使用 TCP。

关于java - 从 UDP 服务器发送文件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5244952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com