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

Java 从UDP服务器发送文件时出现问题,java,udp,byte,Java,Udp,Byte,我正在用Java编写一个小型UDP服务器。 当服务器收到命令(“GET_VIDEO”)时,他读取一个文件(“VIDEO.raw”),然后将其发送给客户端。我的问题是,从服务器发送的字节数不等于客户端接收的字节数,因此测试失败。以下是服务器代码: public class ServerMock { public static void main(String[] args) throws Exception { byte[] buff = new byte[64]; Datag

我正在用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();
    }

}
public void客户端(int超时,字符串消息)
抛出SocketTimeoutException,SocketException{
试一试{
File File=新文件(“./video/tmp.raw”);
FileOutputStream fos=新的FileOutputStream(文件);
File filein=新文件(“./video/video.raw”);
InetAddress=InetAddress.getByName(主机);
byte[]data=message.getBytes();
字节[]缓冲区=新字节[64000];
DatagramSocket套接字=新DatagramSocket();
socket.setSoTimeout(超时);
DatagramPacket数据包=新的DatagramPacket(data,data.length,
地址、港口);
socket.send(包);
DatagramPacket rpacket=新的DatagramPacket(buffer,buffer.length);
while(true){
插座接收(rpacket);

如果(rpacket.getLength()UDP不可靠,则无法保证您将接收所有发送的UDP数据包,或者您将按照发送的顺序接收这些数据包。您需要用序列号标记每个数据包,您需要在客户端对其重新排序,您需要告诉服务器何时减慢速度(或实现确认机制),您将需要请求重新传输的能力


简言之,除非客户端对丢失和无序的数据包感到满意(就像大多数流式客户端一样),您将需要通过UDP重新实现TCP,或者只使用TCP。

UDP不可靠,无法保证您将接收所有发送的UDP数据包,或者您将按照发送顺序接收数据包。您需要用序列号标记每个数据包,您需要在客户端上重新排序,您需要告知当服务器速度减慢(或实现确认机制)时,您将需要请求重新传输的能力


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

我正在搜索从UDP服务器发送文件的示例,发现了您的问题。您必须修改以下行:

在服务器中:

    int size = 0;
    byte[] buffer = new byte[(int) file.length()];
    ByteBuffer bb = ByteBuffer.allocate(4);
    bb.order(ByteOrder.BIG_ENDIAN);
此外,您还必须移动“socket.send(packet)”:


在客户端中,使用
fos.write(rpacket.getData());
修改
fos.write(rpacket.getData(),0,rpacket.getLength());
我正在搜索从udp服务器发送文件的示例,发现了您的问题。您必须修改以下行:

在服务器中:

    int size = 0;
    byte[] buffer = new byte[(int) file.length()];
    ByteBuffer bb = ByteBuffer.allocate(4);
    bb.order(ByteOrder.BIG_ENDIAN);
此外,您还必须移动“socket.send(packet)”:


在客户端中,使用
fos.write(rpacket.getData());
修改
fos.write(rpacket.getData(),0,rpacket.getLength());

您还可能得到重复的数据报和丢失的数据报。您还可能得到重复的数据报和丢失的数据报。