2
votes

I'm trying to use Smack to transfer a file between two PCs connected on the same XMPP server, but I get a weird error.

To summarize, the destination PC has a FileTransferListener registered, like so:

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");
    }
  }
});

The source PC uses an OutgoingFileTransfer like so:

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;
}

When I try to send a file, the outgoing file transfer begins, and the destination PC receives the request, but the source PC cannot go further then the transfer negotiation.

This is seen in the source PC output...

Initial

0.0

2 sec sleep

Negotiating Transfer

0.0

2 sec sleep

Negotiating Stream

0.0

2 sec sleep

Transfer failed: null

I'm really annoyed because I don't even get a proper error message, so I don't really know what went wrong.

Has this ever happened to anyone else?

2
im facing the same issue in smack 4.2.0. I cannot figure out the work around. I get stuck on Negotiating Stream.Rahul Agrawal

2 Answers

3
votes

Looks like you are running into a known issue in Smack that will hopefully be fixed in the next release.

Update: This is now fixed and will be in version 3.2.1.

1
votes

XMPP bytestreams are well specified, but are a rather complex topic, because there is more than one way to establish such a stream. Your code looks right on a quick review. Now the next step would be to analyze the XMPP stanzas send between both clients and the server. This should give you a hint about the error cause. Also make sure to use smack 3.2.0 which has IBB support, which should increase the chance of a successful file transfer via XMPP.