使用 Smack 进行文件传输不起作用
我尝试使用 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秒睡眠
传输失败:空
我真的很生气,因为我什至没有收到正确的错误消息,所以我真的不知道出了什么问题。
其他人也遇到过这种情况吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您在 Smack 中遇到了已知问题,希望能够在下一个版本。
更新:此问题现已修复,并将在版本 3.2.1 中修复。
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.
XMPP 字节流已明确指定,但它是一个相当复杂的主题,因为建立这种流的方法不止一种。
快速查看您的代码看起来不错。现在,下一步是分析客户端和服务器之间发送的 XMPP 节。这应该会提示您错误原因。另请确保使用具有 IBB 支持的 smack 3.2.0,这应该会增加通过 XMPP 成功传输文件的机会。
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.