QT下的多线程TCP客户端和服务器

这篇具有很好参考价值的文章主要介绍了QT下的多线程TCP客户端和服务器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

qt下的QTcpSocket在同一个线程使用时没有问题的,但是如果进行跨线程,很容易出现问题。那么有什么方法可以跨线程进行使用吗?

答案是肯定的:使用QThread的movetothread可以完成扩线程接收。

首先是基于QTcpSocket的类 头文件tcpsocket.h

#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <QTcpSocket>
#include <QHostAddress>

class TcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
	explicit TcpSocket( QObject *parent = NULL);
	explicit  TcpSocket(int socketdesc, QObject *parent = NULL);
    ~TcpSocket();
	bool tcpConnect(const QString ip, const int port);
signals:
	void socketSendData(const QString);
public slots:
    bool start_connt(const QString IP, const int Port);
	void WriteToData(const QByteArray basend);
	void ReadAndParseData();
    void SocketErr(QAbstractSocket::SocketError socketError);
	void slotConnect();
private:
    QString m_recvDataStr;
};

#endif // TCPSOCKET_H

然后是cpp文件tcpsocket.cpp

#include "tcpsocket.h"
#include <QDateTime>


TcpSocket::TcpSocket(QObject *parent /*= NULL*/) : QTcpSocket(parent)
{

	
}




TcpSocket::TcpSocket(int sock, QObject *parent) : QTcpSocket(parent)
{
	this->setSocketDescriptor(sock);
	connect(this, SIGNAL(readyRead()), this, SLOT(ReadAndParseData()));
	connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError)));
	connect(this, SIGNAL(connected()), this, SLOT(slotConnect()));
	connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));

}



TcpSocket::~TcpSocket()
{


}

bool TcpSocket::tcpConnect(const QString ip, const int port)
{

	//this->abort();
	this->connectToHost(ip, port);
	bool recCon = this->waitForConnected(1000000);
	if (recCon)
	{
		connect(this, SIGNAL(readyRead()), this, SLOT(ReadAndParseData()));
		connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError)));
		//connect(this, SIGNAL(connected()), this, SLOT(slotConnect()));
		//connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
		//write("Connect!!");
	}
	return recCon;


}

bool TcpSocket::start_connt(const QString IP, const int Port)
{
	
	  
	    this->abort();
		this->connectToHost(IP, Port);
		this->waitForConnected();
		return true;



}
void TcpSocket::slotConnect()
{
	qDebug() << "slotConnect";

}
// 将会移进线程里面运行
void TcpSocket::ReadAndParseData()
{
	int byteLen = 0;
	QString recvStr = "";
	//wait forreadyread()
	//if (this->waitForReadyRead(0))
	{
		byteLen = this->bytesAvailable();

		if (byteLen>0)
		{

			QByteArray readNet = this->readAll();
			recvStr = QString::fromLatin1(readNet);
		}

	}

	QDateTime tim = QDateTime::currentDateTime();
	QString curtime = tim.toString("yyyy:MM:dd:hh:mm:ss:zzz");
	qDebug() << curtime << "    socket read data:" << recvStr;
	
	emit socketSendData(recvStr);
   


}

void TcpSocket::SocketErr(QAbstractSocket::SocketError socketError)
{
    TcpSocket *socket = (TcpSocket*)sender();
    qDebug()<<"sock err= "<< socketError;
}

void TcpSocket::WriteToData(const QByteArray basend)
{

	
	this->write(basend);
	
}


再次基础上,创建tcpserver.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QThread>
#include <QList>
#include "tcpsocket.h"
class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit  TcpServer( QObject *parent = NULL);
    ~TcpServer();
    void WriteToClient(const QByteArray  strData );
	bool openServer(const QString IpAddress, const  int PortNum);
signals:
    void dataWrite( const QByteArray );
	void serverSend(const QString); 
protected:
    void incomingConnection(qintptr socketDescriptor);
private slots:
    void disconnectSlot();
	void readDataSlot(const QString recdata);
private:
    QList<TcpSocket*> m_socketList;
};




#endif // TCPSERVER_H

和 tcpserver.cpp

#include "tcpserver.h"
#include <QDateTime>

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

}

TcpServer::~TcpServer()
{
	/*   QList<TcpSocket*>::iterator it = m_socketList.begin();
	   for (; it != m_socketList.end(); )
	   {
	   TcpSocket* sock = *it;
	   it = m_socketList.erase(it);
	   sock->deleteLater();
	   sock = NULL;
	   }
	   m_socketList.clear();*/
    this->close();

}

bool TcpServer::openServer(QString IpAddress, int PortNum)
{
	bool bsucc;
	if (IpAddress.isEmpty())
	{
		bsucc = this->listen(QHostAddress::AnyIPv4, PortNum);
	}
	else
	{
	
		bsucc = this->listen(QHostAddress(IpAddress), PortNum);
	}

	return bsucc;
}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{
	
    TcpSocket *socket = new TcpSocket(socketDescriptor);
    m_socketList.append(socket);
    //外部调用信号连接

	connect(socket, SIGNAL(socketSendData(const QString)), this, SLOT(readDataSlot(const QString))); // 会移进线程里


    QThread *thread = new QThread();
     connect(socket, SIGNAL(disconnected()), thread, SLOT(quit()));//线程退出
     connect(socket, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
	 connect(this, SIGNAL(dataWrite(const QByteArray)), socket, SLOT(WriteToData(const QByteArray)));

    connect(thread,SIGNAL(finished()),socket,SLOT(deleteLater()));//删除socket

    socket->moveToThread(thread);
    thread->start();
    emit newConnection();   //文档要求继承本函数需要发射此信号,此处没有与此信号连接的槽
}

void TcpServer::disconnectSlot()
{
    qDebug()<<"disconnect  ok";
}

void TcpServer::readDataSlot(const QString recvStr)
{

	QDateTime tim = QDateTime::currentDateTime();
	QString curtime = tim.toString("yyyy:MM:dd:hh:mm:ss:zzz");
	qDebug() << curtime << "    server read data:" << recvStr;
   
	serverSend(recvStr);
	  
	
}

void TcpServer::WriteToClient(const QByteArray  strData )
{
	
	emit dataWrite(strData);
	
}

在调用的时候分为客户端和服务器两种


	if (m_cell->m_servSel<1)						//客户端
	{
		m_tcp = new  TcpSocket();
		bRet = m_tcp->tcpConnect(IpAddress, PortNum);
		if (bRet)
		{
			work_th = new QThread();
			// ui---线程 交互

			connect(this, SIGNAL(sig_send(const QByteArray)), m_tcp, SLOT(WriteToData(const QByteArray)));
			connect(m_tcp, SIGNAL(disconnected()), work_th, SLOT(quit()));//失去连接后线程退出
			//connect(m_tcp, SIGNAL(disconnected()), this, SLOT(disconnectSlot()));
		
			{
				connect(m_tcp, SIGNAL(socketSendData(const QString)), this, SLOT(rec_tcpClientData(const QString))); // 会移进线程里
			}
		
			connect(work_th, SIGNAL(finished()), m_tcp, SLOT(deleteLater()));//线程退出后删除socket


		
			m_tcp->moveToThread(work_th); //会移进线程里
			work_th->start();


		}
	
	}
	else  //服务器 服务器的每一个客户端单独开线程,在此处不开。
	{
		m_server = new TcpServer();
		bRet = m_server->openServer(IpAddress, PortNum);
		if (bRet)
		{
			
			
			{
				connect(m_server, SIGNAL(serverSend(const QString)), this, SLOT(rec_tcpServerData(const QString)));
			}
			
		}
		
	}
	

这样就可以完成跨线程的收发了。文章来源地址https://www.toymoban.com/news/detail-796719.html

到了这里,关于QT下的多线程TCP客户端和服务器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT实现TCP通信(服务器与客户端搭建)

    创建一个QTcpServer类对象,该类对象就是一个服务器 调用listen函数将该对象设置为被动监听状态,监听时,可以监听指定的ip地址,也可以监听所有主机地址,可以通过指定端口号,也可以让服务器自动选择 当有客户端发来连接请求时,该服务器会自动发射一个newConnection信号

    2024年02月09日
    浏览(54)
  • QT TCP客户端实现

    QTcpSocket实例首先是通过connectToHost()尝试连接到服务器,需要指定服务器的IP地址和端口。connectToHost()是异步方式连接服务器,不会阻塞程序运行,连接后发射connected()信号。 如果需要使用阻塞方式连接服务器,则使用waitForConnected()函数阻塞程序运行,直到连接成功或失败。

    2024年02月09日
    浏览(47)
  • 了解多人游戏下的客户端与服务器体系结构

    直连模式下,选择一个玩家充当服务器(房主)。如果游戏出现不同步,那么均按房主的世界来,玩家1可以作弊修改其游戏来影响其他玩家的世界 针对两个玩家来说,直连连接质量更好,延迟小 如果玩家数量很多,不同玩家间的通信则需要靠房主为中介,那通信质量与房主

    2024年02月12日
    浏览(36)
  • QT-使用QTcpSocket建立TCP客户端连接

    使用QT的QTcpSocket建立TCP客户端方式,十分的简单,上手也快,代码量不多,并且还自动支持重连接机制,也就是说如果你的服务端突然死机了,然后服务端又重启,那么我们的客户端这个时候是会自动去再连接的,不需要你的程序再做重连接的机制,所以我们应用起来是十分

    2024年02月14日
    浏览(43)
  • TCP实现服务器和客户端通信

    目录 TCP介绍 代码实现 server(服务器端) 代码分析 client(客户端) 代码分析 结果展示 TCP (Transmission Control Protocol) 是一种面向连接的协议,用于在计算机网络中传输数据。TCP 可以确保数据的可靠传输,即使在网络环境不稳定的情况下也能够保证数据的完整性和顺序。以下是

    2024年02月15日
    浏览(56)
  • 【Qt专栏】Qt实现TCP服务端和客户端通信

    网络通信是程序员必须会的一项生存技能,这里简单的实现了服务端和客户端通信的两个小示例,代码可以直接拿来用,开发环境是Qt5.9.6。 1.项目架构 2.tcpserver.h文件 3.tcpserver.cpp文件 4.测试效果 1.项目架构 2.tcpserver.h文件 3.tcpserver.cpp文件 4.测试效果 好了,两个小程序写完并

    2024年02月12日
    浏览(36)
  • Qt中使用TCP服务端及客户端

    TCP(Transmission Control Protocol)是一种可靠、高度优化的互联网通信协议,广泛用于各类网络应用程序中。在这篇博客中,我们将介绍如何在Qt中使用TCP服务端及客户端。 要使用Qt创建TCP服务器,需要完成以下步骤: 步骤1:创建QTcpServer对象 步骤2:监听连接请求 在开始监听之前

    2024年02月15日
    浏览(55)
  • 简易TCP客户端和服务器端通信

    #includeiostream #include winsock2.h   #include ws2tcpip.h   #includestdlib.h using namespace std; #define  BUF_SIZE  1024 int main() {     cout \\\"客户端\\\" endl;     //设置Winsock版本,     WSADATA   wsaData;     if (WSAStartup(MAKEWORD(2, 2), wsaData) != 0)     {         cout \\\"error\\\" endl;         exit(1);     }     //创建通

    2024年04月29日
    浏览(47)
  • TCP服务器监测客户端异常退出方法

            作为服务器必须得具备监测客户端状态得机制,以保证客户端处于不同的状态,服务器进行不同得状态处理,依次来提高实时性,可控性,并且有利于服务器得内存管理。其中客户端得异常处理就属于其中得一种。         客户端得断开情形无非就两种情况:

    2024年02月09日
    浏览(50)
  • TCP客户端及服务器端开发实践

    ① TCP客户端应用程序开发 ② TCP服务器端应用程序开发 客户端程序是指运行在用户设备上的程序,服务端程序是指运行在服务器设备上的程序,专门为客户端提供数据服务。那如何记忆呢? 主动发起建立连接请求的是客户端程序,等待接受连接请求的是服务端程序。 开发流

    2024年04月09日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包