【问题标题】:File transfer using Smack doesn't work使用 Smack 传输文件不起作用
【发布时间】:2011-08-28 06:25:42
【问题描述】:

我正在尝试使用 Smack 在连接在同一 XMPP 服务器上的两台 PC 之间传输文件,但我收到了一个奇怪的错误。

总而言之,目标 PC 注册了一个 FileTransferListener,如下所示:

ftm.addFileTransferListener(new FileTransferListener() {
  @Override
  public void fileTransferRequest(FileTransferRequest request) {
    System.out.println("Request received");
    if (true) // Check to see if the request should be accepted
    {
      // Accept it
      System.out.println("Entering FTListener because of FTRequest");
      IncomingFileTransfer transfer = request.accept();
      String id = request.getDescription();
      String path = savePoint + System.getProperty("file.separator") + request.getFileName();

      try
      {
        System.out.println("Receiving...");
        transfer.recieveFile(new File(path));
        // Information put in HashMap for later retrieval
        System.out.println("IM - putting in path (" + id + "," + path + ")");
        paths.put(id, path);
      } catch (XMPPException e) {
        logger.error("Error getting the VM file: " + e.getMessage());
      }
    }
    else
    {
      // Reject it
      request.reject();
      logger.info("VM file transfer rejected");
    }
  }
});

源 PC 使用 OutgoingFileTransfer,如下所示:

try
{
  String nick = destHost + "@" + this.conn.getServer() + "/Smack";
  //destHost = destination host name, conn = XMPP connection
  System.out.println("OFT to " + nick);
  OutgoingFileTransfer.setResponseTimeout(10000);
  OutgoingFileTransfer oft = ftm.createOutgoingFileTransfer(nick);
  oft.sendFile(f, name); //f = file to send, name = a message
  while (!oft.isDone())
  {
    if (oft.getStatus().equals(Status.error))
    {
      System.out.println("ERROR!!! " + oft.getError());
      oft.cancel();
      return false;
    }

    System.out.println(oft.getStatus());
    System.out.println(oft.getProgress());
    System.out.println("5 sec sleep");
    Thread.sleep(5000);
  }

  if (oft.getStatus().equals(Status.complete))
  {
    System.out.println("Transfer done");
    return true;
  }

  if (oft.getStatus().equals(Status.error))
    System.out.println("Transfer failed: " + oft.getError());
  return false;

} catch (XMPPException e) {
  System.out.println("Error sending VM image file with the FTM : " + e.getMessage());
  return false;

} catch (InterruptedException e) {
  System.err.println("Error sleeping during OFT : " + e.getMessage());
  return false;
}

当我尝试发送文件时,传出文件传输开始,目标 PC 收到请求,但源 PC 无法进行传输协商。

这可以在源 PC 输出中看到...

初始

0.0

2 秒睡眠

协商转让

0.0

2 秒睡眠

协商流

0.0

2 秒睡眠

传输失败:null

我真的很生气,因为我什至没有收到正确的错误消息,所以我真的不知道出了什么问题。

其他人有没有遇到过这种情况?

【问题讨论】:

  • 我在 smack 4.2.0 中面临同样的问题。我无法弄清楚解决方法。我卡在协商流上。

标签: xmpp file-transfer smack


【解决方案1】:

XMPP 字节流被很好地指定,但它是一个相当复杂的话题,因为建立这样一个流的方法不止一种。 您的代码在快速审查时看起来很正确。现在下一步是分析客户端和服务器之间发送的 XMPP 节。这应该给你一个关于错误原因的提示。还要确保使用支持 IBB 的 smack 3.2.0,这应该会增加通过 XMPP 成功传输文件的机会。

【讨论】:

  • 我设法使用我的代码将文件从客户端发送到使用 Pidgin 的客户端。明天我将不得不尝试使用我的代码分析两个客户端之间的流量。
  • 我尝试使用 pidgin 将文件发送到我的应用程序。我收到错误消息:“无法打开带内字节流”。在该节中,隐含的 XMPP 错误是数字 404,“无法与任何提供的主机建立套接字”。可能是因为应用程序在经过 NAT 的虚拟机中运行?
  • 带内字节流 (IBB) 是 NAT 保存的,因为它们使用用于 XMPP 消息的现有 XMPP 连接进行数据传输。在粘贴箱上进行文件传输所涉及的节的完整抄本会很有帮助。 IBB 和消息“无法与任何提供的主机建立套接字”并不真正适合在一起。
【解决方案2】:

看起来您在 Smack 中遇到了 known issue,希望在下一个版本中得到修复。

更新:现在已修复,将在版本 3.2.1 中。

【讨论】:

    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2018-11-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多