【问题标题】:weird characters while reading text and binary from a socket's stream in java从java中的套接字流中读取文本和二进制文件时出现奇怪的字符
【发布时间】:2024-04-11 15:40:03
【问题描述】:

我试图寻找一个没有运气的答案(在谷歌和 *)

我正在编写一个Java程序,其中服务器和客户端可以通过发送/接收数据和文件进行通信......

我以每个 1MB 的块发送文件。为了让客户端知道块的数量,我发送了一个包含 BlockNb=x 的字符串行,其中 x 是块的数量,后跟文件。

但是,当我从客户端读取它时,我收到的不是这一行而是一些奇怪的字符:ur\u0000\u0002[B¬ó\u0017ø\bTà\u0002\u0000\u0000xp\u0000\u0000\bP 其中\b\uxxxx 是它们的值的代表(我在这里期待BlockNb=1

(写得更清楚:ur [B¬ó ø Tà xp P(其中空格是转义字符)

这是我的代码。
服务器端

try (
        ServerSocket welcome = new ServerSocket(6500);
        Socket socket = welcome.accept();
        ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
        PrintWriter printWriter = new PrintWriter(socket.getOutputStream())
    )
    {
        System.out.println("accepted");
        File f = new File("...");  //the file path
        try (
            FileInputStream fileInputStream = new FileInputStream(f)
        )
        {
            long length = f.length();
            byte[] buffer;
            //here I put only the code that was executed
            buffer = new byte[(int) length];
            printWriter.println("BlockNb=1");

            fileInputStream.read(buffer);
            outputStream.writeObject(buffer);

            printWriter.println("}");
        }
    }

客户端

try (
        Socket socket = new Socket("localhost", 6500);
        ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
        FileOutputStream fileOutputStream = new FileOutputStream("C:/D/test.txt");
        Scanner scanner = new Scanner(socket.getInputStream())
    )
    {
        String msg = scanner.nextLine();  //the weird string was read at this point
        long blockNb = Long.parseLong(msg.split("BlockNb=", 2)[1]);
        byte[] file = (byte[]) inputStream.readObject();
        fileOutputStream.write(file);
    }

P.S.:当我(仅)从服务器端删除最后 3 行时,一切正常。我按预期收到了BlockNb=1。所以问题只有在两种数据/两种输出流混合使用时才会出现

英语是我的第三语言,如果语法错误或用词不当请见谅

编辑:这里的主要问题是我忘了刷新流。但是,当我刷新流时,我开始收到 EOFException(如果我应用读/写排序,我可以在调试中避免这种情况 - 存在一种同步问题)所以我使用了 QuickSilver 的解决方案,该解决方案除了刷新之外还有效。

【问题讨论】:

    标签: java sockets stream


    【解决方案1】:

    我会避免使用两个不同的对象来写入和读取同一个流。尝试只使用服务器端的 ObjectOutputStream 和客户端的 ObjectInputStream。以与处理缓冲区相同的方式处理字符串:

    服务器:outputStream.writeObject("BlockNb=1");

    客户:String blockNbStr = inputStream.readObject();

    【讨论】:

    • 我发现了我的问题:我忘了刷新流。但我遇到了另一个问题。万一我找不到它,我将使用您的解决方案。谢谢(我不知道你可以通过writeObject 发送String 我以为它只用于SerializableString 不是)
    最近更新 更多