QTcpSocket服务器 定时器,多线程结合

QTcpsocket 写服务器程序时,需要定时向客户端发送监控数据,同时需要响应客户端请求。
问题是: QTcpSocket 只能在同一个线程中使用,定时器会在主线程中运行
解决方案:在定时器中发送信号给封装的客户端数据处理socket,并在线程中将该信号与socket中的操作相连接。
//clientsocket.h
#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H

#include <QTcpSocket>
#include <QTimer>

class ClientSocket : public QTcpSocket
{
	Q_OBJECT

public:
	ClientSocket(QObject *parent);
	~ClientSocket();

signals:
	void sigReadData(const QString &data);

public slots:
	void slotTimeOut();
	void slotReadyRead();
	void slotWriteData(const QString& data);

private:
	QTimer* _timer;

};

#endif // CLIENTSOCKET_H

// clientSocket.cpp
#include "clientsocket.h"
#include <QDebug>

ClientSocket::ClientSocket(QObject *parent)
	: QTcpSocket(parent)
{
	connect(this, &QAbstractSocket::readyRead, this, &ClientSocket::slotReadyRead);

	//_timer = new QTimer(this);
	//connect(_timer, &QTimer::timeout, this, &ClientSocket::slotTimeOut);
	//_timer->start(2000);
}

ClientSocket::~ClientSocket()
{

}

void ClientSocket::slotReadyRead()
{
	QString recv = readAll();
	emit sigReadData(recv);

}

void ClientSocket::slotTimeOut()
{
	write(QByteArray(this->objectName().toStdString().c_str()));
}

void ClientSocket::slotWriteData(const QString& data)
{
	write(data.toStdString().c_str());
	flush();
}

//serverListener.h
#ifndef SERVERLISTENER_H
#define SERVERLISTENER_H

#include <QTcpServer>
#include <QTimer>
#include "clientsocket.h"

class ServerListener : public QTcpServer
{
	Q_OBJECT

public:
	ServerListener(QObject *parent);
	~ServerListener();

	virtual void incomingConnection(qintptr handle);

signals:
	void sigWriteData(const QString& data);

public slots:
	void slotReadData(const QString& data);
	void slotSendMMIDataTimeOut();

private:
	ClientSocket *_clientSock;
	QTimer* _timer;

};

#endif // SERVERLISTENER_H

//serverListener.cpp
#include "serverlistener.h"
#include <QThread>
#include <QDebug>

ServerListener::ServerListener(QObject *parent)
	: QTcpServer(parent)
{

}

ServerListener::~ServerListener()
{

}

void ServerListener::incomingConnection(qintptr handle)
{
	_clientSock = new ClientSocket(0x00);
	_clientSock->setSocketDescriptor(handle);

	QThread *thread = new QThread(this);
	_clientSock->moveToThread(thread);
	_timer = new QTimer(this);
	connect(_clientSock, &ClientSocket::sigReadData, this, &ServerListener::slotReadData);
	connect(this, &ServerListener::sigWriteData, _clientSock, &ClientSocket::slotWriteData);
	connect(_timer, &QTimer::timeout, this, &ServerListener::slotSendMMIDataTimeOut);

	_timer->start(2000);
	thread->start();
}

void ServerListener::slotReadData(const QString& data)
{
	qDebug() << data;
}

void ServerListener::slotSendMMIDataTimeOut()
{
	QString data = QString::fromLocal8Bit("Ryan data");
	//_clientSock->write(data.toStdString().c_str()); //如果在这里的话,就会报错
	emit ServerListener::sigWriteData(data);
}

//main.cpp
#include "serverlistener.h"
#include <QtCore/QCoreApplication>
#include <QHostAddress>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	ServerListener listener(0x00);
	listener.listen(QHostAddress::Any, 6000);

	return a.exec();
}

时间: 2024-10-31 18:43:58

QTcpSocket服务器 定时器,多线程结合的相关文章

Linux高性能服务器编程——多线程编程(上)

多线程编程 Linux线程概述 线程模型 线程是程序中完成一个独立任务的完整执行序列,即一个可调度的实体.根据运行环境和调度者的身份,线程可分为内核线程和用户线程.内核线程,在有的系统上也称为LWP(Light Weigth Process,轻量级进程),运行在内核空间,由内核来调度:用户线程运行在用户空间,由线程库来调度.当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程.可见,内核线程相当于用于线程运行的容器.一个进程可以拥有M个内核线程和N个用户线程,其中M≤N.并且在一

Linux高性能服务器编程——多线程编程(下)

多线程编程 条件变量 如果说互斥锁是用于同步线程对共享数据的访问的话,那么条件变量则是用于线程之间同步共享数据的值.条件变量提供了一种线程间的通信机制:当某个共享数据达到某个值得时候,唤醒等待这个共享数据的线程. 条件本身是由互斥量保护的.线程在改变条件状态前必须首先锁住互斥量,其他现成在获得互斥量之前不会察觉到这种变化,因为必须锁住互斥量以后才能计算条件. 条件变量的相关函数主要有如下5个: #include <pthread.h> int pthread_cond_destroy(pthr

简易聊天程序教程(三)服务器的多线程

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686 如果有什么问题,欢迎留言. 如果一个服务器只能为两个用户提供服务器,那就真的是太渣了.很多时候,聊天的客户都会大于两个.因此需要提高并发量. 在Java中使用多线程还是很方便的.我在这个服务器程序使用的是实现Runnable接口的方法来定义自己的多线程操作.通过重写run方法,来实现自己的多线程操作. 每个线程都会有一个client成员变量,这个成员变量用来记录客户端的Soc

关于游戏服务器是多线程还是单线程的讨论

最近做有关于游戏服务器用单线程的好还是多线程的好的讨论 有同学问:服务端逻辑全单线程的模型,为了避免查询离线玩家数据造成阻塞,除了启动服务器全部加载以外还有更好的办法吗? 同学B: 单线程逻辑模型也属于很常用.逻辑本身不容易出问题. IO得全部分出去. 同学B: 用异步加载事件.数据加载完成后.再重新把任务排入单线程任务队列. 同学C: 各种活动NPC打完就要从场景消失  战斗线程和场景线程分不开 同学C: 场景线程依赖战斗的结果 同学C: 战斗的结果会影响NPC在场景的动态显示 同学C: 然后

Linux网络编程——tcp并发服务器(多线程)

tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建.据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为"轻量级"进程.线程与进程不同的是:一个进程内的所有线程共享相同的全局内存.全局变量等信息,这种机制又带来了同步问题. tcp多线程并发服务器框架: 我们在使用多线程并发服务器时,直接使用以上框架,我们仅仅修改client_fun()里面的内容. 代码示例: #

服务器定时器的管理优化(思路借鉴)

作为一个游戏服务器,必然有很多定时器的使用,算是游戏服务器开发的基础模块,我们经常需要在我们预期的某个时间点执行某项特定的操作.比如每天M点开启某个活动,N小时后之后刷新排行榜等等.这些功能通常需要定时器控制,之前我们的服务器代码中每加一个延迟执行的功能就启动一个定时器,这样到最后往往代码特别臃肿,而且定时器时稀缺资源,过多的定时器必然导致效率问题,于是要想办法优化. 想要优化定时器就要看定时器一共有多少种: 1.只执行一次的定时器,比如60秒后执行操作A. 2.循环执行的定时器,比如每隔30分

1.2socket服务器使用多线程

socket服务器代码如下 from socket import * import time import threading,_thread as thread myHost = '' #''说明所有IP都可以连接 myPort = 50007 #设置一个端口 socketobj = socket(AF_INET,SOCK_STREAM) #创建TCP对象 socketobj.bind((myHost,myPort)) #绑定端口 socketobj.listen(5) #允许5个请求连接 d

TCP通信 - 服务器开启多线程与read()导致服务器阻塞问题

TCP通信的文件上传案例 本地流:客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流 网络流:客户端和服务器之间读写,必须使用Socket中提供的字节流对象 客户端工作:读取本地文件,上传到服务器,读取服务器回写的数据 明确数据源 目的地:服务器 客户端代码: package cn.learn.web; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; impor

2高并发服务器:多线程服务器

 1多进程并发服务器 在使用线程模型开发服务器时需要考虑以下问题: A 调整进程最大文件描述符上限 B 线程如有共享数据,考虑线程同步 C 服务于客户端线程退出时,退出处理 D 2.案例说明 server.c,代码如下: /* server.c */ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthr