如何实现在一个线程内新建QTcpSocket且实现定时判定socket是否连接成功

zkh 2012-08-03 03:45:36
已实践的是在工程中新建一个network类,继承于QThread,network内有一个QTcpSocket指针,network中startTimer一个timer,重载timeEvent.
问题是,如果在run中new QTcpSocket,则timeEvent中定时判断QTcpSocket是否连接会跨线程访问;而如果在network中new,这run访问QTcpSocket会跨线程访问.
不知道我理解是否有误,且该如何实现.
...全文
2578 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
xujianxiang 2015-03-01
  • 打赏
  • 举报
回复
QTcpSocket 不是有isxonnected?
大卫无限 2015-02-05
  • 打赏
  • 举报
回复
这是不使用timer,而使用timerEvent的版本.

#ifndef MYSOCKETTHREAD_H
#define MYSOCKETTHREAD_H

#include <QObject>
#include <QTimer>
#include <QThread>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>

class MySocketThread : public QObject
{
    Q_OBJECT
public:
    MySocketThread() : m_pQTcpSocket(new QTcpSocket), m_pQThread(new QThread())
    {
        m_pQThread->start();

        m_pQTcpSocket->moveToThread(m_pQThread);
        this->moveToThread(m_pQThread);

        connect(this, SIGNAL(DoConnectToHost()),
                this, SLOT(OnConnectToHost()));
        connect(m_pQTcpSocket, SIGNAL(connected()),
                this, SLOT(OnConnected()));
        connect(this, SIGNAL(DoStartTimer()),
                this, SLOT(OnStartTimer()));

        emit DoStartTimer();
    }

    ~MySocketThread()
    {
        m_pQThread->exit();
        m_pQThread->wait(10 * 1000);
        delete m_pQThread;
    }

    void ConnectToHost()
    {
        emit DoConnectToHost();
    }

protected:
    void timerEvent(QTimerEvent *e)
    {
        qDebug() << "MySocketThread timerEvent:" << QThread::currentThreadId();
        QObject::timerEvent(e);
    }

signals:
    void DoStartTimer();
    void DoConnectToHost();

private slots:
    void OnStartTimer()
    {
        this->startTimer(1000);
    }

    void OnConnectToHost()
    {
        qDebug() << "MySocketThread connectToHost:" << QThread::currentThreadId();
        m_pQTcpSocket->connectToHost(QHostAddress::LocalHost, 8811);
    }
    void OnConnected()
    {
        qDebug() << "MySocketThread connected:" << QThread::currentThreadId();
    }


private:
    QTcpSocket * const m_pQTcpSocket;
    QThread * const m_pQThread;
};

#endif // MYSOCKETTHREAD_H

大卫无限 2015-02-05
  • 打赏
  • 举报
回复

#ifndef MYSOCKETTHREAD_H
#define MYSOCKETTHREAD_H

#include <QObject>
#include <QTimer>
#include <QThread>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>

class MySocketThread : public QObject
{
    Q_OBJECT
public:
    MySocketThread() : m_pQTcpSocket(new QTcpSocket), m_pQThread(new QThread()), m_pQTimer(new QTimer())
    {
        m_pQTimer->setInterval(1000);

        m_pQThread->start();

        m_pQTcpSocket->moveToThread(m_pQThread);
        this->moveToThread(m_pQThread);
        m_pQTimer->moveToThread(m_pQThread);

        connect(m_pQTimer, SIGNAL(timeout()),
                this, SLOT(OnTimerOut()));
        connect(this, SIGNAL(DoStartTimer()),
                m_pQTimer, SLOT(start()));
        connect(this, SIGNAL(DoConnectToHost()),
                this, SLOT(OnConnectToHost()));
        connect(m_pQTcpSocket, SIGNAL(connected()),
                this, SLOT(OnConnected()));

        emit DoStartTimer();
    }

    ~MySocketThread()
    {
        m_pQThread->exit();
        m_pQThread->wait(10 * 1000);
        delete m_pQTimer;
        delete m_pQThread;
    }

    void ConnectToHost()
    {
        emit DoConnectToHost();
    }

signals:
    void DoStartTimer();
    void DoConnectToHost();

private slots:
    void OnConnectToHost()
    {
        qDebug() << "MySocketThread connectToHost:" << QThread::currentThreadId();
        m_pQTcpSocket->connectToHost(QHostAddress::LocalHost, 8811);
    }
    void OnConnected()
    {
        qDebug() << "MySocketThread connected:" << QThread::currentThreadId();
    }

    void OnTimerOut()
    {
        qDebug() << "MySocketThread timeout:" << QThread::currentThreadId() << m_pQTcpSocket->isWritable();
    }


private:
    QTcpSocket * const m_pQTcpSocket;
    QThread * const m_pQThread;
    QTimer  * const m_pQTimer;
};

#endif // MYSOCKETTHREAD_H
能给你一定的启发了吗,你可以在外面打印一下线程ID,对比一下这个类里面打印的ID,是不是一样的.
QQ_278397935 2015-02-04
  • 打赏
  • 举报
回复
来个大牛给贴结了呗,,,这个问题我也遇见了。希望有大牛开坛论道。
windyshin 2012-10-19
  • 打赏
  • 举报
回复
迫不得已只能这样找人了。各位见怪莫怪啊~~哈哈~~
windyshin 2012-10-19
  • 打赏
  • 举报
回复
哪位的工作是用到QT开发的???哪位专业人士啊??

可联系我,广州指点传媒集团 HR. 邮箱:syting@y6.cn
Jonix 2012-10-19
  • 打赏
  • 举报
回复
同样问题,顶一下。
tsk 2012-09-02
  • 打赏
  • 举报
回复
QTcpSocket会跨线程访问有问题吗?
xiebin133 2012-08-04
  • 打赏
  • 举报
回复
线程死循环? 没有调用 exec();那样根本没进入事件循环,你怎么进入槽函数?
zkh 2012-08-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

线程死循环? 没有调用 exec();那样根本没进入事件循环,你怎么进入槽函数?
[/Quote]
有调exec,只是不是重点没说而已,先调的exec,再进的死循环,进了槽函数的.
zkh 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

把定时器那段屏了看还有提示么。要再run里创建才行, 在构造创建肯定会出现这样提示的。
[/Quote]
是的,我是在run里new的timer,屏了之后由于没有调用槽函数就没报错.
情况是这样的:run是new QTcpSocket,然后new QTimer,然后一个死循环接收数据,槽函数里面判断QTcpSocket是否连接成功.
一开始运行run,qDebug<<thread()显示run是子线程中,然后执行到new QTimer后马上报一个跨线程,然后去了循环,timeout了去槽,槽内qDebug<<thread()也显示是在子线程中,槽中调用了QTcpSocket的connectToHost和waitForConnected都分别报一个跨线程.
xiebin133 2012-08-03
  • 打赏
  • 举报
回复
把定时器那段屏了看还有提示么。要再run里创建才行, 在构造创建肯定会出现这样提示的。
zkh 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

可以在外面new, 然后通过 moveToThread方法 将对象移到线程里面, 也可以用你的猜想一,对象在run里面new的,他的槽函数是在该线程执行。
[/Quote]
发现原因了,没有执行exec,qdebug<<thread()发现槽函数确实是在子线程中执行,不过槽函数中访问QTcpSocket还是出现QObject: Cannot create children for a parent that is in a different thread.错误.
xiebin133 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
引用 2 楼 的回复:

可以在外面new, 然后通过 moveToThread方法 将对象移到线程里面, 也可以用你的猜想一,对象在run里面new的,他的槽函数是在该线程执行。

发现一个很严重的问题,刚刚QTcpSocket不是在run中new,改成在run中new之后timer不定时发timeout了,怎么回事
[/Quote]
connect了吗。对象在run里new,并在run里connect,他的槽函数就会在线程里面执行。
zkh 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

可以在外面new, 然后通过 moveToThread方法 将对象移到线程里面, 也可以用你的猜想一,对象在run里面new的,他的槽函数是在该线程执行。
[/Quote]
发现一个很严重的问题,刚刚QTcpSocket不是在run中new,改成在run中new之后timer不定时发timeout了,怎么回事
xiebin133 2012-08-03
  • 打赏
  • 举报
回复
你说的槽函数是定时器的槽函数把,定时器不能在run里面new,即使在run里new也不是跨线程的。Qt推荐的使用方法是将对象moveto到线程里面。除了几个特殊的类之外,其他的在run里new,并在run里connect,他的槽函数会再线程里执行,具体的你可以百度下。
zkh 2012-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

可以在外面new, 然后通过 moveToThread方法 将对象移到线程里面, 也可以用你的猜想一,对象在run里面new的,他的槽函数是在该线程执行。
[/Quote]
猜想一不行,槽函数访问QTcpSocket会跨线程,槽函数应该是在主线程中执行,已qDeubg<<thread()验证.
你说的moveto,如果moveto了,也会出现跨线程情况?因为一个run访问QTcpSocket,一个槽函数访问,两者所在线程应该不一样.
我觉得我一直陷在跨线程,定时器里面了,有没有什么方法也是可以实现定时访问socket是否连接成功的呢?
xiebin133 2012-08-03
  • 打赏
  • 举报
回复
可以在外面new, 然后通过 moveToThread方法 将对象移到线程里面, 也可以用你的猜想一,对象在run里面new的,他的槽函数是在该线程执行。
zkh 2012-08-03
  • 打赏
  • 举报
回复
猜想一:如果在run中new QTcpSocket,可以再在run内new一个QTimer,不过槽函数在哪里定义呢,如果在network中定义,那槽函数是在主线程中吗,如果是的话那槽函数访问QTcpSocket会跨线程?可以让槽函数在子线程中吗?

16,239

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧