通过套接字作为 byte[] Java 发送和接收 w3c.dom.Document

Send and receive a w3c.dom.Document over socket as byte[] Java

我像这样通过套接字发送文档:

sendFXML(asByteArray(getRequiredScene(fetchSceneRequest())));

 private void sendFXML(byte[] requiredFXML) throws IOException, TransformerException {
    dataOutputStream.write(requiredFXML);
    dataOutputStream.flush();
}

private Document getRequiredScene(String requiredFile) throws IOException, ParserConfigurationException, SAXException, TransformerException {
   return new XMLLocator().getDocumentOrReturnNull(requiredFile);
}

private String fetchSceneRequest() throws IOException, ClassNotFoundException {
    return dataInputStream.readUTF();
}

XMLLocator 的一侧,它找到正确的文档并正确解析它。我通过在控制台中打印整个文档来看到它。 但我无法在客户端处理它,它是通过以下方式获取的:

public static void receivePage() throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] data = new byte[989898];

    int bytesRead = -1;
    while((bytesRead = dataInputStream.read(data)) != -1 ) { //stops here
        baos.write(data, 0, bytesRead );
    }

    Files.write(Paths.get(FILE_TO_RECEIVED), data);
}

while() 循环中的第一次迭代后,它就停在注释的地方。 我不知道服务器端是否有错误,我以错误的格式在文档中发送了这个错误,或者我错误地读取了发送的字节数组。问题出在哪里?

编辑: 出于调试目的,在 receivePage() 方法中,我选择了一种不同的方式从服务器读取字节数组,如下所示:

    int count = inputStream.available();
    byte[] b = new byte[count];
    int bytes = dataInputStream.read(b);
    System.out.println(bytes);
    for (byte by : b) {
        System.out.print((char)by);
    }

现在我可以在控制台中打印获取的 FXLM,但出现了一个新问题。 在调试时,它通常从服务器接收 byte[],为 count 写入 2024 并显示文件的内容,但是如果我 运行 该应用程序通常通过 Shift + f10 获取任何内容,只是在控制台中写入 0

编辑2: 出于某种原因,再一次,在调试时,它甚至能够写入文件

for (byte by : b) {
   Files.write(Paths.get(FILE_TO_RECEIVED), b);
   System.out.print((char)by);
}

但是当我尝试 return 调试这个 fxml 然后像这样显示时:

Parent fxmlToShow = FXMLLoader.load(getClass().getResource("/network/gui.fxml"));
Scene childScene = new Scene(fxmlToShow);
Stage window = (Stage)((Node)ae.getSource()).getScene().getWindow();
window.setScene(childScene);
return window;

它只显示以前的文件。就像第一次尝试调试一样,当我从服务器请求第一个时,它显示一个空白页面。在第二次尝试调试时,当我从服务器请求第 3 页时,它向我显示了之前请求的页面,依此类推。 对我来说,这似乎绝对是疯了,因为 fxml 规则实际上在行

之前刷新
Parent fxmlToShow = FXMLLoader.load(getClass().getResource("/network/gui.fxml"));

被调用。

嗯,谢谢大家的参与。 因此,FXML 文件显示不正确的问题是由不正确的 FILE_TO_RECEIVED 路径引起的。 当 FXMLLoader.load(getClass().getResource("/network/gui.fxml")); 加载 gui.fxml 时,它不是从 D:\JetBrains\IdeaProjects\Client\src\network\gui.fxml 中获取,我的情况是,而是从 D:\JetBrains\IdeaProjects\Client\OUT\PRODUCTION\Client\network\gui.fxml 中获取。 对于我来说,这似乎并不明显。

调试和 运行 上的不同行为呢?在方法 receivePage() 中需要等待连接可用。

int count = inputStream.available();

如果您阅读有关此方法的文档,您会看到

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream ... The available method for class InputStream always returns 0...

因此,您接下来需要等待连接可用

while(inputStream.available()==0){
        Thread.sleep(100);
}

否则它只是准备 byte[] b = new byte[count]; 0 个字节,你什么也不能写。