【问题标题】:Why is my data missing from my file after transfering it over a socket?为什么我的数据在通过套接字传输后从文件中丢失?
【发布时间】:2015-08-18 18:46:27
【问题描述】:

在尝试将文件上传到服务器或从服务器下载文件时,我为服务器和客户端编写了相同的代码。

从服务器下载工作正常,我的文件中没有任何数据丢失,但由于某种原因,在上传文件时,并没有全部传输。

例如,我的客户端上的文件大小比服务器上的要小。然后在服务器上打开的时候,并不是全部都在(因为不是全部都收到了)

服务器:

算法:

  • 从客户端获取消息
  • 客户端告诉服务器它要发送文件(推送)

服务器读取文件存放位置,然后从客户端接收文件

  public static void GetClientMessage() {

            while (true) {
                try {

                    try {

                        try {
                            serverSocket = new ServerSocket(PORT_NUMBER);
                        } catch (IOException ex) {
                            System.out.println("GetClientMessage():serverSocket:IOException:ex " + ex);
                            SendBackException(ex.toString());  // Inform client
                        }
                        try {
                            System.out.println("Waiting for client");
                            socket = serverSocket.accept();
                        } catch (IOException ex) {
                            System.out.println("GetClientMessage():socket = serverSocket.accept():IOException:ex " + ex);
                            SendBackException(ex.toString());  // Inform client
                        }

                        bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

                        // 1 - Read Line (it is the flag)
                        flag = brffReadIn.readLine();
                        // 2 - Handle Flag
                        HandleClientMessage(flag);

                        // Make decisions based upon that message
                    } catch (IOException ex) {
                        System.out.println("GetClientMessage():IOException:ex: " + ex);
                        SendBackException(ex.toString());  // Inform client
                    }

                    socket.close();
                    serverSocket.close();

                } // Close while loop
                catch (IOException ex) {
                    System.out.println("GetClientMessage:serverSocket.close():IOException:ex " + ex);
                }

            }

        }

           public static void HandleClientMessage(String message) {
           System.out.println("HandleClientMessage:message: '" + message + "'");
            switch (message) {
                case "push":
                    GetClientFile();
                    break;
                case "open_cla":
                    OpenCla();
                    break;
                case "kill_cla":
                    KillCla();
                    break;
                case "get":                
                    SendFile();
                    break;
                default:
                    break;
            }
        }

        // Gets path to where to place file on local
        public static String GetPath() {

            String filePath = " ";

            try {

                bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

                filePath = brffReadIn.readLine();

                System.out.println("Path to place file on local: " + filePath);

            } catch (IOException ex) {
                System.out.println(("GetPath():IOException:ex: " + ex));
            }
            return filePath;
        }

        public static void GetClientFile() {

            // Get the location where to place the file on local
            fileOnLocal = GetPath();

            int count;
            try {

                File file = new File(fileOnLocal);
                // Get the size of the file
                long length = file.length();
                byte[] bytes = new byte[16* 1024];
                InputStream in = socket.getInputStream();
                OutputStream out = new FileOutputStream(fileOnLocal);

                while ((count = in.read(bytes)) > 0) {
                    System.out.println("strByteArray: " + strByteArray);
                    out.write(bytes, 0, count);
                }
                out.flush();

                System.out.println("File Size in bytes: " + file.length());
                if (file.length() < 5) {
                    System.out.println("FileClient:Error:File:" + fileOnLocal + " not found on server");
                    out.close();
                    in.close();
                    socket.close();
                    file.delete();
                    System.out.println("File:" + file.getAbsolutePath() + " deleted");
                } else {
                    out.close();
                    in.close();
                    socket.close();
                }

            } catch (IOException ex) {
                System.out.println(":FileClient:GetServerFile():IOException:ex:" + ex);
            }
        }

客户代码:

客户端告诉服务器它想要“推送”一个文件,然后它传递将文件放在服务器上的位置,然后传输文件

public void SendFlagToServer(String flag){

        try {

            bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

            bufOut.write(flag);
            bufOut.newLine();
            bufOut.flush();

            System.out.println(host + ":SendFlagToServer: " + flag);

        } catch (IOException ex) {
            Logger.Log((host + ":FileClient:SendFileToGetToServer():IOException:ex: " + ex));
        }
    }

执行此操作后,客户端会收到字节,但不是全部。有什么我编码错了吗?我的 byte[] 数组应该是不同的大小吗?这将在 Win7 和 Win8 上使用,未来可能还会在 Mac 上使用。

编辑:我想通了。我试图发送一条消息后跟一串字节太快了。

这解决了我的问题:

SendFlagToServer(fileLocaitonOnServer);
Thread.sleep(1000);
....

【问题讨论】:

    标签: java sockets tcp ftp


    【解决方案1】:

    您在第一次客户端连接后关闭套接字

    socket.close();
    serverSocket.close();
    

    解决方案:

    • 一旦你接受了一个客户端套接字,就用这个套接字连接创建一个新线程并处理该线程中的所有 IO 操作

    • 不要关闭 serverSocket。关闭 serverSocket 后,将不再接受客户端套接字连接。

    你能提供你得到的例外吗?

    【讨论】:

    • 即使在进行更改后也会出现相同的问题。我没有收到任何信息,我客户端上的文件大小为 7.69kb,传输到服务器后为 6.32kb。
    • 我想通了...我试图发送文件太快,所以延迟 1 秒。我会用答案更新我的问题。感谢您的帮助。
    • 我认为这种延迟有助于重新创建 serverSocket,因为您正在关闭它。切勿在您的应用程序中关闭 serverSocket 并立即尝试
    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多