【问题标题】:Send and receive a w3c.dom.Document over socket as byte[] Java通过套接字发送和接收 w3c.dom.Document 作为 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,但出现了一个新问题。 在调试时,它通常从服务器接收字节 [],为 count 写入 2024 并显示文件的内容,但如果我通过 Shift 正常运行应用程序+ f10 它什么都不获取,只是在控制台中写入 0

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

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 激怒实际上在行前刷新

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

被调用。

【问题讨论】:

    标签: arrays sockets client-server domdocument file-writing


    【解决方案1】:

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

    所以,你需要等待连接可用

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

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

    【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 2016-12-08
      • 2015-05-12
      • 1970-01-01
      • 2012-02-12
      • 2013-09-11
      • 1970-01-01
      • 2012-10-05
      相关资源
      最近更新 更多