• 10154阅读
  • 14回复

QT线程run中是不是不能写socket接受程序? [复制链接]

上一主题 下一主题
离线liangwenkuai
 

只看楼主 倒序阅读 楼主  发表于: 2013-12-06
QT线程run中是不是不能写socket接受程序啊?没有发送数据过来,窗体能正常显示,但是只要发送数据过来,程序就出错了。我是想实现,程序一运行主窗体显示出来,并且还有一个线程开启,接受数据,如果有数据,就把数据以emit出去,对应的槽函数是在窗体上新建一个button
void CThreadClass::run()

{
    int err;
    while (1)
    {
        err = recvfrom(m_sockClient, (char *)&m_fplData, vBufLengh, 0, (SOCKADDR*)&m_addrToMachine, &len);//接收数据
        emit UpdateSignal1(1);
        Sleep(1000);
    }
                    

    closesocket(m_sockClient);WSACleanup();
}
离线friendbaby

只看该作者 1楼 发表于: 2013-12-07
接收到数据出错,说明问题出在了槽函数中。
你提到槽函数中是在窗体上新建一个button,由此推断,你的信号和槽函数是直连的,也就是槽函数是次线程执行的。而次线程是不允许操作UI的。
你可以打开控制台窗口,看一看输出信息。
Smiling is best language , can express everything , also can conceal everything.
离线liangwenkuai

只看该作者 2楼 发表于: 2013-12-07
回 楼主(liangwenkuai) 的帖子
但是奇怪的是,没有recvfrom这个接收语句,就能正常执行,emit一个数据,slot就能处理,并动态出现一个button
离线liangwenkuai

只看该作者 3楼 发表于: 2013-12-07
回 1楼(friendbaby) 的帖子
不明白为什么会这样.但是奇怪的是,没有recvfrom这个接收语句,就能正常执行,emit一个数据,slot就能处理,并动态出现一个button,。
离线XChinux

只看该作者 4楼 发表于: 2013-12-07
这样用QThread很奇怪。你还不如用moveToThread()
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 5楼 发表于: 2013-12-07
楼主详细了解下 QThread和 QtConcurrent的用法,再决定如何写。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线liangwenkuai

只看该作者 6楼 发表于: 2013-12-07
你说的这样用QThread奇怪是指不能在run里面写接收程序吗?
离线friendbaby

只看该作者 7楼 发表于: 2013-12-07
为什么不使用QUdpSocket呢
Smiling is best language , can express everything , also can conceal everything.
离线liangwenkuai

只看该作者 8楼 发表于: 2013-12-07
回 4楼(XChinux) 的帖子
这样用QThread奇怪是指不能在run里面写接收程序吗?
离线XChinux

只看该作者 9楼 发表于: 2013-12-07
你在这个run()里调用下下面的代码:
qDebug() << QThread::currentThreadId()

在main()函数里调用下
qDebug() << QThread::currentThreadId()

看看两者的值。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线liangwenkuai

只看该作者 10楼 发表于: 2013-12-07
回 7楼(friendbaby) 的帖子
现在用,QUdpSocket了,但是为什么接收到数据以后,增加一个button,窗体上没有显示出来,而是等把所有的数据都收到以后,才显示出来?
线程中的run方法:void CThreadClass::run()
{
    m_pSocket= new QUdpSocket(NULL);
    m_pSocket->bind(9900);
    connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
    exec();
}
接收程序
void CThreadClass::processPendingDatagrams()
{
    while (m_pSocket->hasPendingDatagrams())
    {
        FLYDataStruct::FPLDataStruct fplDataStruct;
        m_pSocket->readDatagram((char *)&fplDataStruct, sizeof(fplDataStruct));
        emit UpdateSignal1(1);
        //exec();
    }
}
下面是槽函数对应emit的信号的
void CWidget::UpdateSlot(int vStruct)
{
    if (vStruct != 0)
    {
        QPushButton *btn = new QPushButton("lwk");
        layout->addWidget(btn);
    }
}
这是connect:    connect(m_pThread, SIGNAL(UpdateSignal1(int)), this, SLOT(UpdateSlot(int)));
离线friendbaby

只看该作者 11楼 发表于: 2013-12-07
回 10楼(liangwenkuai) 的帖子

我不了解你的数据是什么,你可以测试只发送一次数据,并且在processPendingDatagrams打印一下
Smiling is best language , can express everything , also can conceal everything.
离线liangwenkuai

只看该作者 12楼 发表于: 2013-12-07
回 11楼(friendbaby) 的帖子
数据就是一个结构体类型,能够正常接收到数据,数据也是对的。
void CThreadClass::processPendingDatagrams()
{
    while (m_pSocket->hasPendingDatagrams())
    {
        FLYDataStruct::FPLDataStruct fplDataStruct;
        m_pSocket->readDatagram((char *)&fplDataStruct, sizeof(fplDataStruct));
        emit UpdateSignal1(1);//接收到数据的话,就会执行emit,信号函数的参数是个整形(这里测试用,每次都是1,数据的话没有影响)
        //exec();
    }
}
下面是槽函数对应emit的信号的
void CWidget::UpdateSlot(int vStruct)
{
    if (vStruct != 0)
    {
        QPushButton *btn = new QPushButton("lwk");
        layout->addWidget(btn);
    }
}
现在是程序启动界面出现,当对方发来一个数据的时候(因为是调试使用,所以是在循环里发送数据),窗体会增加一个button(当发送第一个数据过来的时候可以),但是再发送数据过来的时候,就不会增加button了(数据还是能正常接收到,信号,槽函数都能正常执行,但是往后窗体上就不增加button了。)实在是不清楚到底是为什么。
离线liangwenkuai

只看该作者 13楼 发表于: 2013-12-07
回 11楼(friendbaby) 的帖子
能加好友吗?论坛上不太好聊
离线friendbaby

只看该作者 14楼 发表于: 2013-12-09
回 13楼(liangwenkuai) 的帖子
QQ 327079704
Smiling is best language , can express everything , also can conceal everything.
快速回复
限100 字节
 
上一个 下一个