#ifndef TFTPC_H_
#define TFTPC_H_
#ifdef __cplusplus
extern "C" {
#endif
unsigned int tftp_client_send_file(const char *url, const char *hostaddr ,const int targetport);
#ifdef __cplusplus
};
#endif
#endif // TFTPC_H
On Thu, Sep 29, 2011 at 11:04:55AM +0800, Kitty Wu wrote:
> 最近在做英特尔的比赛,我们做的是基于wifi的文件传输,
> 现在遇到了些问题,向大家寻求帮助指导,问题阐述如下:
>
> 1,QT内转码问题,
> 描述: 传输文件,文件名出现乱码,(文件名是英文或者中文,都出现乱码),但是文件内容是正确的:
可能是你的文件名的编码出问题了(Utf8和GBK之间的转换),这个问题一般使用QTextCodec解决的,你看看这个类。
> 我们使用的文件传输协议的tftp协议,
> tftp包格式是:| Opcode | Filename | 0 | Mode | 0 | 第一个包,
> 从第二个包开始传输文件内容,按字节传输,每个块512B
>
> 使用linuxC代码实现,通过qt调用进行文件传输,在qt中声明了C, 代码如下:
>
>
> #ifndef TFTPC_H_
>
> #define TFTPC_H_
>
> #ifdef __cplusplus
>
> extern "C" {
>
> #endif
>
> unsigned int tftp_client_send_file(const char *url, const char
> *hostaddr ,const int targetport);
>
>
> #ifdef __cplusplus
>
> };
>
> #endif
>
> #endif // TFTPC_H
>
>
> 然后在qt中的一个类方法中调用tftp_send_file(),
> 问题就在这里,qt中我们获得url类型是QString,在传参时我们已将url的类型进行了转换,
> 尝试了几种转换但是传输的文件,文件名依然是乱码, 尝试的转换类型有url.toAscii(), url.toLocal8bit(),
光toXXX不行,还要看看你fromXXX的时候对不对。
还是看:QTextCodec。
> 一直尝试着把QString转换成char*类型然后调用C接口.
> 但是都以失败告终...想知道..这个是否牵扯到Qt的内转码问题? 应该如何解决?
> 2,关于Qt UI冻结问题:
> 问题阐述:
> 在qt 的主进程中调用了从c++的一个方法,此方法中使用qthread创建了一个线程去跑上面我提到的tftp传输函数,
> 这ui在传输过程中冻结了...
> 我知道Qt中解决ui冻结的最好方法是使用信号-槽机制,
信号和槽严格地讲不是解决UI冻结的,是使用QApplication::processEvents()在处理的过程中处理其它的事件。这是个小技巧,但低效,而且不一定适合所有情况。真正处理UI冻结的办法的多线程。
bool send_file::send_file_to_remote(QString url, QString address, int port)
{send_file_thread thread(url);
thread.set_target(address, port);
thread.start();
thread.wait();
return true;
}qml我没有用过,我认为那个东西一般是用作UI美工和程序员沟通和演示用的,真正做界面我绝对不会用它。
> 但是现在由于我的上层界面使用的是qml写的(还不是很熟),我正在尝试在qml中发送信号,在C++中接收并创建线程去跑传输,
当然可以。
> 我想要询问:如果不使用信号槽,使用线程,是否可以?个人想法如下:
一般是自己实现一个QThread的子类,尤其是他的run()方法,那个方法里的东西都会在一个新的线程中跑,相当与C语言中在pthread_create()中通过void *(*start_routine) (void *)指定的线程函数一样。
> 1,使用moveToThread()把这个传输线程抛到另一个线程中去运行,有人知道如何使用moveToThread方法么?找了些资料,但是说的很范,不会使用.
> 还有这个线程应该是由谁去创建?主进程?
我没有用过moveToThread(),
它用的是UI主线程的资源,但是主线程不会冻结,他俩并行地跑。你看看QThread就知道了,一般吧要传递给线程的参数和其它资源作为QThread子类的成员,也就是说,你可以使用指针或者引用来访问任何你想要的父类资源。
> 2,在当前已创建的线程上再创建线程去跑传输...这个就是线程上再创建线程,,,可是第二个线程的父亲是谁?它使用的是谁的资源... ui主线程?
> 这样做ui还是会freez,对么?
> PS:附加一个关于qml的问题,希望了解qml的童鞋帮忙解答一下...
>
> 1,qml中接收C++信号问题..
> 当我们文件传输完毕后,会发送一个信号(filesent()),有qml接收,并在图形界面显示相关信息, 成功/失败,
> 现在出现的问题是: C++发送的signal, qml中没有接收到.
> 使用的是Connections{}属性, onFileSent:触发qml动作, Connections{ }
> 放置在需要响应的qml元素中,某个Rectangle
>
> 结果是qml无法响应C++信号..
我没有用过qml,但你可以用qml写个最简单的HelloWorld试试,如果不行,可以把代码贴出来我帮你看看。
> 希望我已经把问题描述清楚了,求助解答...
> 明天就提交复赛作品了,还有这几个问题..木有解决~~
> 请高手指导呀~~
> 拜谢先~~
>
> --
>
> Regards~
>
> 吴云
B.R
Kermit
On Thu, Sep 29, 2011 at 05:06:05PM +0800, Kitty Wu wrote:
> gmail又有点问题,我们的情况是这样的..
> UI调用了C++的一个方法,这个方法中创建了线程(代码如下),就像您说的ui主线程会和run()中的函数并行的跑,这样ui是应该不会冻结的啊..可是测试..ui是freeze
> 了..直到这个线程结束....
>
>
> bool send_file::send_file_to_remote(QString url, QString address, int port)
>
> {
>
> send_file_thread thread(url);
>
> thread.set_target(address, port);
>
>
> thread.start();
>
> thread.wait();
//你这里的wait()吧ui线程阻塞了,不要加这个。
//thread结束后会自己发一个finished()信号出来的,通过
//它去获取相应状态进行处理。
void send_file_thread::run() // probelm here
{
int retval;
qDebug("inner sending thread ------------------------- start");
retval = tftp_client_send_file(_url.toAscii(),_host.toAscii(), _port);
if (retval < 0) {
qDebug("fail to send file");
emit failedToSend();
} else {
qDebug("send file successfully");
emit fileSent();
}
qDebug()<< "++++++++++++" << qPrintable(_url);
qDebug("inner sending thread ------------------------- end");
}
> return true;
>
> }
>
B.R
Kermit
<snip>
> 开始我也觉得是wait把线程阻塞了,当去掉此句后,
> 传输动作出发后,会出现如下错误:
不用想,肯定是Wait造成的阻塞;出现错误则是另外一个问题。
> QThread: Destroyed while thread is still running
> Segmentation fault
>
> 然后界面就死掉了`~~
你的thread对象是不是局部变量(最好不要使用局部变量来操作QThread),亦或是你手动delete删除了?
最简单的办法是自己通过finished()信号来处理结果。删除QObject子类的对象时,用deleteLater()方法能够帮助你避开这些问题。
> 还有就是,我的传输信号是在run中通过调用C方法返回值去发出的..(还是看代码好说话
> ),所以我想是不是就可以不用考虑thread的结束状态了..让它运行完自己destory掉就好了..还是说必须对其结束状态进行处理?(抱歉..第一次真正用qt开发..很多东西都不清楚..看了很多文档,但还是有点模糊~)
> void send_file_thread::run() // probelm here
>
> {
>
> int retval;
>
> qDebug("inner sending thread ------------------------- start");
>
> retval = tftp_client_send_file(_url.toAscii(),_host.toAscii(), _port);
//上面这个函数会阻塞,对么?
> if (retval < 0) {
>
> qDebug("fail to send file");
>
> emit failedToSend();
>
> } else {
>
> qDebug("send file successfully");
>
> emit fileSent();
>
> }
>
> qDebug()<< "++++++++++++" << qPrintable(_url);
>
> qDebug("inner sending thread ------------------------- end");
>
> }
>
>
> > > return true;
> > >
> > > }
B.R
Kermit