Warm tip: This article is reproduced from serverfault.com, please click

arrays-通过套接字以字节[]的形式发送和接收w3c.dom.Document Java

(arrays - Send and receive a w3c.dom.Document over socket as byte[] Java)

发布于 2020-12-27 16:49:24

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

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()循环中的第一次迭代之后,它仅停留在已注释的位置。我不知道服务器端是否有错误,是否以不正确的格式在doc中发送此错误,或者我未正确读取发送的字节数组。问题出在哪儿?

编辑: 出于调试目的,在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 [],写入2024进行计数并显示文件的内容,但是如果我通过Shift + f10正常运行应用程序,则它什么也不会获取,只是在控制台中写入0

Edit2: 由于某种原因,再次在调试时,它甚至可以写入文件

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

但是,当我尝试在调试时返回此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;

它仅显示以前的文件。就像第一次调试一样,当我从服务器请求第一个页面时,它会显示一个空白页面。在第二次尝试调试时,当我从服务器请求第三页时,它向我显示了先前询问的内容,依此类推。在我看来,fxml rile实际上在行之前刷新绝对是疯狂的

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

被调用。

Questioner
63350541
Viewed
0
63350541 2020-12-29 23:53:10

是的,谢谢大家的参与。因此,如果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();

如果你阅读此方法的文档,将会看到

返回可以从此输入流读取(或跳过)的字节数的估计值。InputStream类的可用方法始终返回0 ...

因此,你的jext需要等待连接可用

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

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