File Transfer with Smack Not Working

Hi,

I am using the code below for File Transfer with the Smack api but for some reason I am not seeing the file being transfered at all. In my driver program when I check the status of the transfer, it is always in “Negotiating Transfer” state. However, in the smack debugger it is showing that the file is sent from client A to B and Client B received it. I don’t know what is going on. I am using smack and openfire. I also made sure that File transfer is enable on the server(Openfire)

Plz help me solve this.

Thanks,

Emmanuel

public void fileTransfer(String fileName, String destination) throws XMPPException {

    // Create the file transfer manager
    FileTransferManager manager = new FileTransferManager(connection);

    FileTransferNegotiator.setServiceEnabled(connection, true);
    // Create the outgoing file transfer
    OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(destination);
    // Send the file
    transfer.sendFile(new File(fileName), "You won't believe this!");
  
   
    while (!transfer.isDone()) {
        if (transfer.getStatus().equals(Status.error)) {
            System.out.println("ERROR!!! " + transfer.getError());
        } else {
            System.out.println(transfer.getStatus());
            System.out.println(transfer.getProgress());
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(SimpleSmackClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

public void fileReceiver(final boolean accept, final String fileName) {
    // Create the file transfer manager
    final FileTransferManager manager = new FileTransferManager(connection);

    // Create the listener
    manager.addFileTransferListener(new FileTransferListener() {

        public void fileTransferRequest(FileTransferRequest request) {
           
            // Check to see if the request should be accepted
            if (accept) {
                // Accept it
                IncomingFileTransfer transfer = request.accept();
                try {
                    transfer.recieveFile(new File(fileName));
                } catch (XMPPException ex) {
                    ex.printStackTrace();
                }
            } else {
                // Reject it
                request.reject();
            }
        }
    });
}

OK. I got this figured out. I was a coding issue caused by me.

i am having the same problem what did you do to resolve the issue?!!!??

Hi,

I don’t remember on top of my mind how I resolved it but I know it has something to do with my own code. Plz send me your code if you want I will help you on this.

Emmanuel

Hi Again @drd6y

I created a small driver program that you can use in order to see how File Transfer works with the Smack API.

In order for this program to work you gonna have to:

  • create 2 account(name them however you want)
  • change the host name and service names
  • change the filename you want to transfer

SimpleSmackClient.java

import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferNegotiator;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;

/**
*

  • @author ekakoll
    */
    public class SimpleSmackClient {

public XMPPConnection connection;
private FileTransferManager manager;

public void login(String username, String password) throws XMPPException {
XMPPConnection.DEBUG_ENABLED = true;
ConnectionConfiguration config = new ConnectionConfiguration(“host”, 5222, “host”);
connection = new XMPPConnection(config);
connection.connect();
connection.login(username, password);
manager = new FileTransferManager(connection);
}

public void sendMessage(String message, String destination) throws XMPPException {
Chat chat = connection.getChatManager().createChat(destination,
new MessageListener() {

public void processMessage(Chat c, Message message) {
System.out.println(c.getParticipant() + " says: " + message.getBody());
}
});
chat.sendMessage(message);
}

public void logout() {
if (connection != null) {
connection.disconnect();
}
}

public void fileTransfer(String fileName, String destination) throws XMPPException {

// Create the file transfer manager
//FileTransferManager manager = new FileTransferManager(connection);
FileTransferNegotiator.setServiceEnabled(connection,true);
// Create the outgoing file transfer
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(destination);

// Send the file
transfer.sendFile(new File(fileName), “You won’t believe this!”);
try {
Thread.sleep(10000);
}
catch(Exception e){}
System.out.println("Status :: " + transfer.getStatus() + " Error :: " + transfer.getError() + " Exception :: " + transfer.getException());
System.out.println("Is it done? " + transfer.isDone());
}

public void fileReceiver(final boolean accept, final String fileName) {
// Create the file transfer manager
//final FileTransferManager manager = new FileTransferManager(connection);

// Create the listener
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(FileTransferRequest request) {
// broadcast something here. Wheather users want to accept file
// Check to see if the request should be accepted
if(accept) {
// Accept it
IncomingFileTransfer transfer = request.accept();
try {
transfer.recieveFile(new File(fileName));
System.out.println("File " + fileName + “Received Successfully”);
//InputStream input = transfer.recieveFile();
} catch (XMPPException ex) {
Logger.getLogger(SimpleSmackClient.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
// Reject it
request.reject();
}
}
});
}
}

User.java

/**
*

  • @author ekakoll
    */
    public class User {
    private String userName;
    private String password;
    protected static SimpleSmackClient ssc;

/**
* @return the userName
*/
public String getUserName() {
return userName;
}

/**
* @param userName the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}

/**
* @return the password
*/
public String getPassword() {
return password;
}

/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}

UserAkem.java:

package poc;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.jivesoftware.smack.XMPPException;

/**
*

  • @author ekakoll
    */
    public class UserAkem extends User {

public void init() throws Exception {
setUserName(“akem”);
setPassword(“akem”);
ssc = new SimpleSmackClient();
ssc.login(this.getUserName(), this.getPassword());
}

public void sendMessage(String message, String destination) throws XMPPException {
ssc.sendMessage(message, destination);
}

public void logout() {
ssc.logout();
}

public void fileTransfer(String fileName, String destination) throws XMPPException {
ssc.fileTransfer(fileName, destination);
}

public void fileReceiver(final boolean accept, final String fileName) {
ssc.fileReceiver(accept, fileName);
}

public static void main(String[] args) throws Exception {
UserAkem uak = new UserAkem();
uak.init();

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String message = null;
while (!(message = br.readLine()).equalsIgnoreCase(“bye”)) {
ssc.sendMessage(message, “akolly@host”);
}

// Send file to user akolly

uak.fileTransfer(“D:\Documents and Settings\ekakoll\Desktop\Book Review.txt”,“akolly@host/Smack”);

//uak.logout();
}
}

UserAkolly.java

package poc;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.jivesoftware.smack.XMPPException;

/**
*

  • @author ekakoll
    */
    public class UserAkolly extends User {

public void init() throws Exception {
setUserName(“akolly”);
setPassword(“akolly”);
ssc = new SimpleSmackClient();
ssc.login(this.getUserName(), this.getPassword());
}

public void sendMessage(String message, String destination) throws XMPPException, XMPPException {
ssc.sendMessage(message, destination);
}

public void logout() {
ssc.logout();
}

public void fileTransfer(String fileName, String destination) throws XMPPException {
ssc.fileTransfer(fileName, destination);
}

public void fileReceiver(final boolean accept, final String fileName) {
ssc.fileReceiver(accept, fileName);
}

public static void main(String[] args) throws Exception {
UserAkolly uako = new UserAkolly();
uako.init();

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String message = null;
while (!(message = br.readLine()).equalsIgnoreCase(“bye”)) {
ssc.sendMessage(message, “akem@host”);

// Receive new file. You can give it a new name
uako.fileReceiver(true, “D:\Documents and Settings\ekakoll\Desktop\Received Book Review.txt”);
}

//uako.logout();
}
}

N.B:

I hope this helps. If not let me know

Emmanuel

Hi Kouami,

I am using Smack in Android. I have successfully tansferied message but not the file.

I get the NullPointerException in: FileTransferNegotiator.setServiceEnabled(connection,true);

I am using Android SDk1.5 and the Smack jar is gotten from http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/#comment -2279.

Thanks in advance.

Ethan

skymedichen,

If you are trying to get file transfer working on Android, you need to read the following thread. Because working for android environment is not the same as working for standard java.

http://www.igniterealtime.org/community/message/195679#195679

I think, that smack file transfer is not ready for prime time yet cause I am having issue testing out spark which should be the best implementation of smack.

http://www.igniterealtime.org/community/thread/39665?tstart=0

At first, I thought that 60kb limitation might be triggered by google because they are known not to be xmpp compliant. However I don’t find the 60kb limitation problem when I test out the very basic file transfer implementation (using the example code) between my two android apps using google accounts. I can send file of size 3MB successfully most of the time in a control environment (which is both clients have the same connection speed). I could never send 30MB size tho. I have only tested with these 2 sizes in a control environment.

File transfer cannot transfer file size less than 0.5MB (well 443KB) while the two clients have different connection speeds (DSL to modem or 3G to Edge scenario) when it is from very fast connection speed to the slow connection speed. The fast client will get 503 error and will stop transferring after 200kb. I don’t know if I have to deal with the connection speed myself manually.

I feel disappointed that spark file transfer does not even work out of the box for me in the first place.