文件传输无法正常工作 smack 4.1 android
File Transfer not working smack 4.1 android
目前我正在使用新的 Smack 4.1,它完全支持 android。发送和接收消息没问题,工作正常。但是现在,我陷入了发送和接收文件的困境。例如:
发送文件
public void sendFile(String fileName,String to){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
OutgoingFileTransfer transfer = transferManager.createOutgoingFileTransfer(to);
try {
transfer.sendFile(new File(fileName), "This is a Test!");
} catch (SmackException e) {
e.printStackTrace();
}
}
接收文件
public void setReceiveFileListener(){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
transferManager.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer transfer = request.accept();
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator +"TEST"+File.separator+ "new.txt");
transfer.recieveFile(file);
} catch (SmackException | IOException e) {
e.printStackTrace();
}
}
});
}
在这种情况下,我只是发送了一个文本文件,并希望将其另存为 sd 卡中的新文本文件 "new.txt"。问题不在于文件本身,文件存在。此外,接收者 ID 是正确的,就像 "user@host.com/Smack" 一样。那是我可以成功发送普通消息的同一个接收器。
我从 Smack 得到的错误代码:
错误 503 - 服务不可用
这个错误响应是我在发送文件后直接从 smack 得到的,似乎文件没有传输,因为接收器监听器什么都不显示(我在发送和接收上都做了日志),但监听器肯定是注册的。
但我完全确定,服务器支持文件传输,它在他们的网站上声明 www.coderollers.com 。我在 SO 和 Smack 开发者社区中阅读了很多关于这里的问题。没有任何帮助,所以我的问题是:
- 这个问题可能是什么原因造成的?
- 难道是因为我必须更改端口?
- 如何在 smack 中更改现有连接的端口?
- 文件传输的任何替代方法?
我的正常端口是 5222,可以正常发送消息。我希望有人让它工作并能引导我走向正确的方向....感谢您的帮助!
解决方案
对于所有感兴趣的人:Devendra Singhs 的回答是正确的,我自己做了一点注释。使用哪种资源似乎很重要。从手机到手机,你得用"mobile"。 "Smack" 或任何其他资源标识符都不能在这里工作。所以像这样正确初始化 OutgoingFileTransfer
很重要:
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer
(XmppStringUtils.completeJidFrom(USER, SERV, "mobile"));//important resource "mobile"
研究了很久才搞定
FileTransferManager ftm1 = FileTransferManager.getInstanceFor(connection);
FileTransferManager ftm2 = FileTransferManager.getInstanceFor(connection2);
ftm2.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer ift = request.accept();
try {
InputStream is = ift.recieveFile();
ByteArrayOutputStream os = new ByteArrayOutputStream();
int nRead;
byte[] buf = new byte[1024];
while ((nRead = is.read(buf, 0, buf.length)) != -1) {
os.write(buf, 0, nRead);
}
os.flush();
dataReceived = os.toByteArray();
} catch (SmackException | IOException | XMPPErrorException e) {
e.printStackTrace();
}
if (Arrays.equals(dataToSend, dataReceived)) {
System.out.println("Received data matches send data. \o/");
} else {
System.err.println("Recieved data DOES NOT match send data. :(");
}
}
});
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer(XmppStringUtils.completeJidFrom(USER, SERV, "resourse"));
oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting");
outerloop: while (!oft.isDone()) {
switch (oft.getStatus()) {
case error:
System.out.println("Filetransfer error: " + oft.getError());
break outerloop;
default:
System.out.println("Filetransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress());
break;
}
Thread.sleep(1000);
}
connection.disconnect();
connection2.disconnect();
Thread.sleep(1000);
}
一个连接正在发送文件,另一个连接正在接收这是工作代码。
我遇到了同样的问题,我调查了节并以这种方式解决了它。
许多人使用 "/Smack" 或 "/Resource" 作为 jid 中的资源部分,但这可以通过其他方式完成.
资源路径随着用户的每次存在变化而变化。假设我们要将图像发送给该用户:
"user1@mydomain"
您必须将“/Resource”或“/Smack”部分添加到此 jid,它会变成这样:
user1@mydomain/Resource
但是资源路径会随着在线状态而变化,因此您必须跟随每次在线状态变化来更新资源路径。
最好的方法是让用户出现在花名册侦听器中,在 presencheChanged() 方法中,您可以获得最后一个用户资源部分,如下所示:
Roster roster=getRoster();
roster.addRosterListener(new RosterListener() {
@Override
public void entriesAdded(Collection<Jid> addresses) {
Log.d("entriesAdded", "ug");
context.sendBroadcast(new Intent("ENTRIES_ADDED"));
}
@Override
public void entriesUpdated(Collection<Jid> addresses) {
Log.d("entriesUpdated", "ug");
}
@Override
public void entriesDeleted(Collection<Jid> addresses) {
Log.d("entriesDeleted", "ug");
}
@Override
public void presenceChanged(Presence presence) {
Log.d("presenceChanged", "ug");
//Resource from presence
String resource = presence.getFrom().getResourceOrEmpty().toString();
//Update resource part for user in DB or preferences
//...
}
});
}
资源字符串将是一些生成的字符串,如 "6u1613j3kv" 并且 jid 将变为:
user1@mydomain/6u1613j3kv
这意味着您必须像这样创建传出转账:
EntityFullJid jid = JidCreate.entityFullFrom("user1@mydomain/6u1613j3kv");
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(jid)
在您的情况下,此资源部分是 "mobile"。只需用资源部分从名册侦听器中的存在更改它。
这就是我在 smack 和 Openfire 上解决文件传输问题的方法。
还要提一下,您必须在 Openfire 服务器中添加以下属性:
xmpp.proxy.enabled - true
xmpp.proxy.externalip - MY_IP_ADDRESS
xmpp.proxy.port -7777
顺便提一下,我使用的是 Openfire 4.0.2 和 Smack 4.2.2。
这也可以通过简单的方式配置,只需将资源设置为
XMPPTCPConnectionConfiguration.Builder .
喜欢
XMPPTCPConnectionConfiguration.Builder configurationBuilder =
XMPPTCPConnectionConfiguration.builder();
configurationBuilder.setResource("yourResourceName");
目前我正在使用新的 Smack 4.1,它完全支持 android。发送和接收消息没问题,工作正常。但是现在,我陷入了发送和接收文件的困境。例如:
发送文件
public void sendFile(String fileName,String to){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
OutgoingFileTransfer transfer = transferManager.createOutgoingFileTransfer(to);
try {
transfer.sendFile(new File(fileName), "This is a Test!");
} catch (SmackException e) {
e.printStackTrace();
}
}
接收文件
public void setReceiveFileListener(){
if(transferManager==null) {
transferManager = FileTransferManager.getInstanceFor(mConnection);
}
transferManager.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer transfer = request.accept();
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator +"TEST"+File.separator+ "new.txt");
transfer.recieveFile(file);
} catch (SmackException | IOException e) {
e.printStackTrace();
}
}
});
}
在这种情况下,我只是发送了一个文本文件,并希望将其另存为 sd 卡中的新文本文件 "new.txt"。问题不在于文件本身,文件存在。此外,接收者 ID 是正确的,就像 "user@host.com/Smack" 一样。那是我可以成功发送普通消息的同一个接收器。
我从 Smack 得到的错误代码:
错误 503 - 服务不可用
这个错误响应是我在发送文件后直接从 smack 得到的,似乎文件没有传输,因为接收器监听器什么都不显示(我在发送和接收上都做了日志),但监听器肯定是注册的。 但我完全确定,服务器支持文件传输,它在他们的网站上声明 www.coderollers.com 。我在 SO 和 Smack 开发者社区中阅读了很多关于这里的问题。没有任何帮助,所以我的问题是:
- 这个问题可能是什么原因造成的?
- 难道是因为我必须更改端口?
- 如何在 smack 中更改现有连接的端口?
- 文件传输的任何替代方法?
我的正常端口是 5222,可以正常发送消息。我希望有人让它工作并能引导我走向正确的方向....感谢您的帮助!
解决方案
对于所有感兴趣的人:Devendra Singhs 的回答是正确的,我自己做了一点注释。使用哪种资源似乎很重要。从手机到手机,你得用"mobile"。 "Smack" 或任何其他资源标识符都不能在这里工作。所以像这样正确初始化 OutgoingFileTransfer
很重要:
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer
(XmppStringUtils.completeJidFrom(USER, SERV, "mobile"));//important resource "mobile"
研究了很久才搞定
FileTransferManager ftm1 = FileTransferManager.getInstanceFor(connection);
FileTransferManager ftm2 = FileTransferManager.getInstanceFor(connection2);
ftm2.addFileTransferListener(new FileTransferListener() {
@Override
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer ift = request.accept();
try {
InputStream is = ift.recieveFile();
ByteArrayOutputStream os = new ByteArrayOutputStream();
int nRead;
byte[] buf = new byte[1024];
while ((nRead = is.read(buf, 0, buf.length)) != -1) {
os.write(buf, 0, nRead);
}
os.flush();
dataReceived = os.toByteArray();
} catch (SmackException | IOException | XMPPErrorException e) {
e.printStackTrace();
}
if (Arrays.equals(dataToSend, dataReceived)) {
System.out.println("Received data matches send data. \o/");
} else {
System.err.println("Recieved data DOES NOT match send data. :(");
}
}
});
OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer(XmppStringUtils.completeJidFrom(USER, SERV, "resourse"));
oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting");
outerloop: while (!oft.isDone()) {
switch (oft.getStatus()) {
case error:
System.out.println("Filetransfer error: " + oft.getError());
break outerloop;
default:
System.out.println("Filetransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress());
break;
}
Thread.sleep(1000);
}
connection.disconnect();
connection2.disconnect();
Thread.sleep(1000);
}
一个连接正在发送文件,另一个连接正在接收这是工作代码。
我遇到了同样的问题,我调查了节并以这种方式解决了它。
许多人使用 "/Smack" 或 "/Resource" 作为 jid 中的资源部分,但这可以通过其他方式完成.
资源路径随着用户的每次存在变化而变化。假设我们要将图像发送给该用户: "user1@mydomain"
您必须将“/Resource”或“/Smack”部分添加到此 jid,它会变成这样: user1@mydomain/Resource
但是资源路径会随着在线状态而变化,因此您必须跟随每次在线状态变化来更新资源路径。 最好的方法是让用户出现在花名册侦听器中,在 presencheChanged() 方法中,您可以获得最后一个用户资源部分,如下所示:
Roster roster=getRoster();
roster.addRosterListener(new RosterListener() {
@Override
public void entriesAdded(Collection<Jid> addresses) {
Log.d("entriesAdded", "ug");
context.sendBroadcast(new Intent("ENTRIES_ADDED"));
}
@Override
public void entriesUpdated(Collection<Jid> addresses) {
Log.d("entriesUpdated", "ug");
}
@Override
public void entriesDeleted(Collection<Jid> addresses) {
Log.d("entriesDeleted", "ug");
}
@Override
public void presenceChanged(Presence presence) {
Log.d("presenceChanged", "ug");
//Resource from presence
String resource = presence.getFrom().getResourceOrEmpty().toString();
//Update resource part for user in DB or preferences
//...
}
});
}
资源字符串将是一些生成的字符串,如 "6u1613j3kv" 并且 jid 将变为: user1@mydomain/6u1613j3kv
这意味着您必须像这样创建传出转账:
EntityFullJid jid = JidCreate.entityFullFrom("user1@mydomain/6u1613j3kv");
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(jid)
在您的情况下,此资源部分是 "mobile"。只需用资源部分从名册侦听器中的存在更改它。
这就是我在 smack 和 Openfire 上解决文件传输问题的方法。
还要提一下,您必须在 Openfire 服务器中添加以下属性:
xmpp.proxy.enabled - true
xmpp.proxy.externalip - MY_IP_ADDRESS
xmpp.proxy.port -7777
顺便提一下,我使用的是 Openfire 4.0.2 和 Smack 4.2.2。
这也可以通过简单的方式配置,只需将资源设置为
XMPPTCPConnectionConfiguration.Builder .
喜欢
XMPPTCPConnectionConfiguration.Builder configurationBuilder =
XMPPTCPConnectionConfiguration.builder();
configurationBuilder.setResource("yourResourceName");