【问题标题】:Why socket send only 1KB (425B) of data?为什么socket只发送1KB(425B)的数据?
【发布时间】:2021-04-10 04:28:40
【问题描述】:

我正在学习套接字,现在我想编写文件传输程序。我有服务器部分和客户端部分。服务器部分包含 2 个端口:5000(命令)和 5001(文件)。现在我想通过套接字发送一个文件,当我做错了因为只有 425B 的数据正在发送。

这里是客户端发送方法:

private void sendFile(Socket socket) {
    File file2 = new File("C:\\Users\\barte\\Desktop\\dos.png");
    byte[] bytes = new byte[16 * 1024];
    System.out.println(file2.exists());
    try (InputStream inputStream = new FileInputStream(file2);
        OutputStream outputStream = socket.getOutputStream();
        OutputStream secondOutput = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\dos.png")) {
        int count;
        while ((count = inputStream.read(bytes)) > 0) {
            outputStream.write(bytes, 0, count);
            secondOutput.write(bytes, 0, count);
        }
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如您所见(下图),我也在本地写入此文件,一切正常,73KB 的数据全部写入。

现在,在服务器端,我正在尝试接收此文件:

case SEND: {
   new Thread(() -> {
     printWriter.println("Server is receiving files right now...");
     try (ServerSocket serverSocket = new ServerSocket(5001)) {
       while (true) {
        new FilesTransfer(serverSocket.accept()).start();
       }
     } catch (IOException e) {
        e.printStackTrace();
     }
     }).start();
     break;
   }

在 FilesTransfer 内部运行方法:

@Override
public void run() {
    System.out.println("Hello there");
    try {
        InputStream inputStream = inSocket.getInputStream();
        OutputStream outputStream = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\file");
        byte[] bytes = new byte[16 * 1024];
        int count;
        while ((count = inputStream.read()) > 0) {
            outputStream.write(bytes, 0, count);
        }
        outputStream.close();
        inputStream.close();
        inSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

错误在哪里?为什么在本地一切正常时只发送空字节?

【问题讨论】:

    标签: java sockets inputstream fileoutputstream


    【解决方案1】:

    你可以这样做:

    @Override
    public void run() {
        System.out.println("Hello there");
        try {
            InputStream inputStream = inSocket.getInputStream();
            OutputStream outputStream = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\file");
            byte[] bytes = new byte[16 * 1024];
            int byteRead= 1;
            while (byteRead > -1) {
                byteRead= inputStream.read();
                outputStream.write(byteRead);
            }
            outputStream.close();
            inputStream.close();
            inSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    实际上 END OF FILE 或 EOF 表示 -1 而你做了 > 0 所以取了 0 并且它停止了保存文件的连接。

    我还建议编写一个逻辑,将文件名作为命令传输到服务器,以便以正确的名称和扩展名保存文件!

    【讨论】:

    • 哇,谢谢你,这对我有帮助,所以现在不需要 byte[]bytes 对吗?我还将实现名称和扩展名的逻辑,但我应该在 5000 端口(如文本命令)上执行还是在文件端口中发送?
    • 我建议在用于命令的端口上执行此操作:执行以下操作:从客户端发送关于文件和数据的请求以及关于文件的上传命令以及授权(如果您想要安全)。然后你从服务器发送确认。然后从另一个端口发送文件数据!
    【解决方案2】:

    问题是:

    while ((count = inputStream.read()) > 0) {
    

    您的代码使用InputStream.read(),它读取单个字节(或-1,当流结束时)。现在,您正在读取单个字节,将其解释为长度,然后将 bytes 中的 0x00 字节数写入文件。当您从流中读取 0x00 字节时,这将停止。

    您需要将其更改为使用InputStream.read(byte[])

    while ((count = inputStream.read(bytes)) != -1) {
    

    也就是说,你需要传入bytes,并检查结果是否不等于-1,而不是大于零(0),虽然read(byte[])只会返回0如果传入的字节数组的长度为零,那么这不是一个真正的问题。

    【讨论】:

      猜你喜欢
      • 2019-08-15
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多