【问题标题】:UDP Client Server File TransferUDP 客户端服务器文件传输
【发布时间】:2014-04-20 01:10:06
【问题描述】:

我正在尝试通过 UDP 将数据包从客户端发送到服务器。我面临的问题是,如果最后一个数据包的大小小于我们正在读取的字节数组的大小,那么来自前一个数据包的冗余数据就会被附加到它上面。我尝试只将最后一个数据包的正确部分复制到一个新的字节数组中,然后发送它,但客户端以某种方式只发送了错误的数据包。请任何人指出我做错了什么。提前致谢。

Client.java:

class client
{
static int serverPort;
static String filename;
    public static void main(String args[]) throws SocketException, IOException
    {
        int count=0;
        int MAX_SIZE = 1048;

        DatagramSocket clientSocket = new DatagramSocket();
        InetAddress IpAddress = InetAddress.getByName("localhost");

        byte[] sendData = new byte[MAX_SIZE];

        String filePath = "C:\\in.txt";
        File file = new File(filePath);
        FileInputStream fis = new FileInputStream(file);


        int totLength = 0; 

        while((count = fis.read(sendData)) != -1)    //calculate total length of file
        {
            totLength += count;
        }

        System.out.println("Total Length :" + totLength);

        int noOfPackets = totLength/MAX_SIZE;
        System.out.println("No of packets : " + noOfPackets);

        int off = noOfPackets * MAX_SIZE;  //calculate offset. it total length of file is 1048 and array size is 1000 den starting position of last packet is 1001. this value is stored in off.

        int lastPackLen = totLength - off;
        System.out.println("\nLast packet Length : " + lastPackLen);

        byte[] lastPack = new byte[lastPackLen-1];  //create new array without redundant information


        fis.close();

        FileInputStream fis1 = new FileInputStream(file);
        //while((count = fis1.read(sendData)) != -1 && (noOfPackets!=0))
        while((count = fis1.read(sendData)) != -1 )
        { 
            if(noOfPackets<=0)
                break;
            System.out.println(new String(sendData));
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IpAddress, 9876);
            clientSocket.send(sendPacket);
            System.out.println("========");
            System.out.println("last pack sent" + sendPacket);
        noOfPackets--;
        }

        //check
        System.out.println("\nlast packet\n");
        System.out.println(new String(sendData));

        lastPack = Arrays.copyOf(sendData, lastPackLen);

        System.out.println("\nActual last packet\n");
        System.out.println(new String(lastPack));
                //send the correct packet now. but this packet is not being send. 
        DatagramPacket sendPacket1 = new DatagramPacket(lastPack, lastPack.length, IpAddress,     9876);
        clientSocket.send(sendPacket1);
        System.out.println("last pack sent" + sendPacket1);

    }
}

Server.java:
import java.io.*;
import java.net.*;

class server
{
    public static void main(String args[]) throws IOException
    {
        DatagramSocket serverSocket = new DatagramSocket(9876);
        byte[] recData = new byte[1024];
        int i =0;

        FileWriter file = new FileWriter("C:\\Users\\ayushi\\Documents\\Semester 2\\Misc\\setups\\eclipse\\ip_1\\ip_second\\src\\out.txt");
        PrintWriter out = new PrintWriter(file);


        //BufferedOutputStream bos = new BufferedOutputStream(fos);

        while(true)
        {
            //PrintWriter out = new PrintWriter(file);

            DatagramPacket recPacket = new DatagramPacket(recData, recData.length);
            serverSocket.receive(recPacket);
            String line = new String(recPacket.getData());
            System.out.println("\n Data: " + line);
            out.println(line);
            System.out.println("\nPacket" + ++i + " written to file\n");
            out.flush();
        }
    }
}

【问题讨论】:

    标签: java udp client


    【解决方案1】:

    如果最后一个数据包的大小小于我们正在读取的字节数组的大小,那么来自前一个数据包的冗余数据将被附加到它。

    没有。问题是来自第一个数据包的字节仍然包含在recData 字节数组中。随后的读取将用第二个数据包的内容覆盖字节数组的开头,但数组的其余部分仍由第一个数据包中的数据填充。

    根本问题是您忽略了实际接收的字节数。您还应该使用FileOutputStream,而不是Writer。试试这个:

    class Server
    {
        public static void main(String args[]) throws IOException
        {
            ...
    
            while(true)
            {
                DatagramPacket recPacket = new DatagramPacket(recData, recData.length);
                serverSocket.receive(recPacket);
                System.out.println("\n Packet length: " + recPacket.getLength());
                out.write((recPacket.getData(), 0, recPacket.getLength());
                System.out.println("\nPacket" + ++i + " written to file\n");
                out.flush();
            }
        }
    }
    

    【讨论】:

    • 谢谢。有效。但是代码中还有另一个小问题。在写入新文件时,不会复制 2 3 个字。我检查了所有偏移量和所有内容的值,它应该复制所有内容,但不知何故无法弄清楚。
    • 造成差异的一个原因可能是服务器和客户端使用不同的大小来发送和接收字节数?服务器使用 1024 字节大小,客户端发送 1048。这将在每次服务器接收数据包时“在线”留下 24 个字节。希望对您有所帮助。
    • 另外需要注意的是数据丢失是 UDP 的本质。当您发送 UDP 数据包时,您无法保证一定会收到它。如果您需要保证交付,UDP 将不是一个可行的选择。
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多