关于QT 多线程收发数据的问题

slmax1 2017-09-05 11:36:16
我用QT做客户端

1.如果在主线程中创建QTcpSocket,在子线程调用其write方法会报socket notifiers cannot be enabled from another thread
2.如果在子线程中即创建QTcpSocket,又调用write方法,无任何异常.但抓包发现.数据并没有发送出去.write却又正常返回
3.如果在主线程创建.又调用.不太符合多线程开发.故该方法不考虑


关键代码如下

void SendThread::running()
{
connectToHost();

while (1)
{
if (m_lstData.empty())
{
QThread::sleep(1);
continue;
}

QString xmlStr = m_lstData.front();
m_lstData.pop_front();
emit send(xmlStr);

m_pNet->getTcpSocket()->write(xmlStr.toUtf8());
}
}

void SendThread::connectToHost()
{
//连接服务器
m_pNet = new NetClient;
m_pNet->connectHost(QString("127.0.0.1"), 9999);
connect(m_pNet->getTcpSocket(), &QTcpSocket::connected,
[]()
{
qDebug() << "服务器已连接";
}
);

connect(m_pNet->getTcpSocket(), &QTcpSocket::disconnected,
[]()
{
qDebug() << "服务器已断开";
}
);
}


running()为线程函数
...全文
1888 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
flist 2018-06-28
  • 打赏
  • 举报
回复
在线程中接收与发送TCP数据建议使用moveToThread()的方法去创建线程,然后使用信号触发去接收与发送数据。实测没有问题
渣渣要努力 2018-06-16
  • 打赏
  • 举报
回复
引用 10 楼 csshow 的回复:
[quote=引用 9 楼 Lutx 的回复:] 问题就在于socket对象是在哪里创建, 属于哪个线程.
创建与使用均在子线程.发送不了数据. 创建与使用均在主线程.OK 创建与使用在不同的线程....提示异常..[/quote] 请问楼主,我在写的项目(使用QT)要求客户端用子线程向服务端发送数据,那我应该怎么解决呢?查了好久了,还没找到解决方法,看到您的帖子提出了相同问题,跟您讨教一下经验!盼复~谢谢您了!
slmax1 2017-09-07
  • 打赏
  • 举报
回复
引用 9 楼 Lutx 的回复:
问题就在于socket对象是在哪里创建, 属于哪个线程.
其实我都已经放弃了QT自带的socket了. 现在就是想问下.我用系统API与QT的socket有什么优缺点..除非跨平台的问题.
slmax1 2017-09-07
  • 打赏
  • 举报
回复
引用 9 楼 Lutx 的回复:
问题就在于socket对象是在哪里创建, 属于哪个线程.
创建与使用均在子线程.发送不了数据. 创建与使用均在主线程.OK 创建与使用在不同的线程....提示异常..
Lutx 2017-09-07
  • 打赏
  • 举报
回复
问题就在于socket对象是在哪里创建, 属于哪个线程.
slmax1 2017-09-07
  • 打赏
  • 举报
回复
工作忙.有时候回复慢了点...
slmax1 2017-09-07
  • 打赏
  • 举报
回复
引用 6 楼 Lutx 的回复:
几年前写的一点Qt内线程有关的东西, 不知道对你理解有没有帮助 http://blog.csdn.net/Lutx/article/details/7353957
之前百度到过您的这篇文章.学习了一些知识.不过您的文章没有涉及到socket与线程方面的内容啊. 只是详解了下对象与线程从属的内容.
Lutx 2017-09-07
  • 打赏
  • 举报
回复
几年前写的一点Qt内线程有关的东西, 不知道对你理解有没有帮助 http://blog.csdn.net/Lutx/article/details/7353957
kk999900 2017-09-07
  • 打赏
  • 举报
回复
Qt的socket还不是根据不同的平台调用的系统api而已,底层都是一样的 多线程要注意的一点时,子线程的构造和析构是在主线程里面执行的;如果主线程直接运行子线程的函数和槽函数,其实也是在主线程里运行的;主线程控制子线程可以发信号给子线程,或者使用QMetaObject::invokeMethod来调用子线程的函数,这也是在子线程里执行的
slmax1 2017-09-06
  • 打赏
  • 举报
回复
贴子已加分.欢迎讨论哦.
slmax1 2017-09-06
  • 打赏
  • 举报
回复
已经换回windows系统API来实现了.那个用起来比QT的方便太多.直接把socket扔向子线程就行.不过就是不能跨平台..当然.windows与linux的socket编程本来就相差不大.稍加几个编译指令便可实现跨平台(windows,linux) 不知道这样做与QTcpSocket有什么优缺点.
slmax1 2017-09-05
  • 打赏
  • 举报
回复
m_pNet对socket做了简单封装
  • 打赏
  • 举报
回复
数据没发送出去,可以使用如下方法查一下: 1.tcp连上了没? 2.QTcpSocket有一个void error(QAbstractSocket::SocketError socketError)的信号,写个槽关联该信号看看是否有错误发生 3.“但抓包发现.数据并没有发送出去。“”抓包抓的是本机ip的包吗?如果是本机ip,wirshark抓包需要设置回环loop网络,具体设置方法可以百度一下抓本机的包就有。
橙儿稻香 2017-09-05
  • 打赏
  • 举报
回复
我是在主线程中创建线程 然后在线程中创建socket的 数据发送正常。。。 主线程的button点击 控制 线程中的 socket write 通过 Signal 信号来实现

16,211

社区成员

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

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