QTcpServer服务器(incomingConnection方式)

阅读: 评论:0

QTcpServer服务器(incomingConnection方式)

QTcpServer服务器(incomingConnection方式)

最近没事想着研究一下QT 的服务器,了解了一下QT中相关的接口,突然发现incomingConnection这个方式好简单呀,弄好后测试了一下(没有数据那种,只是简单的收到确认和回复(打开33个client客户端),不保证大批量的数据处理的效率

首先要弄一个数据接收已经处理的socket,只要readyRead和disconnected就行,一个用来接收数据,一个用来销毁连接

// 头文件
#ifndef TCPSOCKET_H
#define TCPSOCKET_H#include <QTcpSocket>class TcpSocket : public QTcpSocket
{Q_OBJECT
public:TcpSocket(QObject *parent = nullptr);signals:void emit_updateClients(QString, int);void emit_disConnected(qintptr);//private slots:
//    void onDataRecv();
//    void onDisconnected();
};#endif // TCPSOCKET_H
// cpp
#include "tcpsocket.h"TcpSocket::TcpSocket(QObject *parent): QTcpSocket (parent)
{connect(this, &QTcpSocket::readyRead, [this](){while (this->bytesAvailable() > 0){int length = this->bytesAvailable();QByteArray size(length);this->read(data.data(), length);                            														// 接受sock数据QString strReadData = QString::number(this->socketDescriptor()) + " " + data;emit emit_updateClients(strReadData, strReadData.length());// for循环是为了模拟,大批量数据处理for(int index = 0; index < 1000000; ++index){}QString strMsg = "Recv Success";this->StdString().c_str(), strMsg.length());								// 给client客户端返回接收情况}});// 调用销毁信号,但是看实际情况,调用这个的时候就销毁了,会导致获取到的描述符为-1, 但是不会影响到其他地方connect(this, &QTcpSocket::disconnected, [this](){qDebug() << this->socketDescriptor();emit emit_disConnected(this->socketDescriptor());               // 获取socket描述符});}

接下来是服务器部分,真的真的超级简单,我都惊了,直接上代码,部分地方会上解释

// 头文件
#ifndef TCPSERVER_H
#define TCPSERVER_H#include <QList>
#include <QTcpServer>#include "TcpServer/tcpsocket.h"class TcpServer : public QTcpServer
{Q_OBJECT
public:TcpServer(QObject *parent = nullptr, int port = 3366);QStringList m_strListData;
signals:void emit_UpdateServer(QString, int);protected:QList<TcpSocket *> list_tcpclient;						// 用来方便管理各个客户端// 用来连接客户端,这个函数需要注意,在QT 5后面的版本参数部分类型要改为 **qintptr** 否则会出现连接上了,但是没有执行函数的情况virtual void incomingConnection(qintptr socketDescriptor);		};#endif // TCPSERVER_H
// cpp
#include "tcpserver.h"
#include <QDebug>TcpServer::TcpServer(QObject *parent, int port): QTcpServer (parent)
{/***************** QHostAddress *  Null            空地址*  LockHost        IPv4 127.0.0.1 本地回环地址*  LockHostIPv6    IPv6           本地回环地址*  Broadcast       广播地址 255.255.255.255*  Any             IPv4 0.0.0.0   任意地址*  AnyIPv6         IPv6           任意地址******************/  this->listen(QHostAddress::Any, port);if(this->isListening()){qDebug() << "isListening";}
}void TcpServer::incomingConnection(qintptr socketDescriptor)
{TcpSocket *socket = new TcpSocket();// 设置本 socket 唯一标识符socket->setSocketDescriptor(socketDescriptor);qDebug() << socketDescriptor << " " << socket->socketDescriptor();// 添加到list中方便管理list_tcpclient.append(socket);// 本 socket 接受到的信息connect(socket, &TcpSocket::emit_updateClients, [this](QString strInfo, int length){// 这个信息要进行什么操作,这里是为了将收到的数据展示m_strListData.append(strInfo);if(m_strListData.size() >= 200){m_strListData.clear();}Q_UNUSED(length);});// 在list中移除,销毁实际是在 TcpSocket 中触发销毁的时候就已经销毁了connect(socket, &TcpSocket::emit_disConnected, [this](int isocketDescriptor){for(int index = 0; index < list_tcpclient.size(); ++index){QTcpSocket *item = list_tcpclient.at(index);qDebug() << list_tcpclient.at(index)->socketDescriptor();qDebug() << item << " socketDescriptor " << item->socketDescriptor() << " " << isocketDescriptor;if(item->socketDescriptor() == isocketDescriptor){veAt(index);return ;}qDebug() << "list size " << list_tcpclient.size();}});
}

UI界面主要就是简单的展示数据,其实上面也看不到,数据有点快

// 主要代码
tcpserver = new TcpServer;connect(timer, &QTimer::timeout, [this](){ui->textEdit->clear();for(int index = 0; index < tcpserver->m_strListData.size(); ++index)ui->textEdit->append(tcpserver->m_strListData.at(index));
});
timer->start(100);

下面介绍一下incomingConnection

原文解释:
This virtual function is called by QTcpServer when a new connection is available. The socketDescriptor argument is the native socket descriptor for the accepted connection.
The base implementation creates a QTcpSocket, sets the socket descriptor and then stores the QTcpSocket in an internal list of pending connections. Finally newConnection() is emitted.
Reimplement this function to alter the server’s behavior when a connection is available.
If this server is using QNetworkProxy then the socketDescriptor may not be usable with native socket functions, and should only be used with QTcpSocket::setSocketDescriptor().
Note: If another socket is created in the reimplementation of this method, it needs to be added to the Pending Connections mechanism by calling addPendingConnection().
Note: If you want to handle an incoming connection as a new QTcpSocket object in another thread you have to pass the socketDescriptor to the other thread and create the QTcpSocket object there and use its setSocketDescriptor() method.

译文:
当有新的连接可用时,QTcpServer将调用这个虚拟函数。socketDescriptor参数是接受连接的本地套接字描述符。
基本实现创建一个QTcpSocket,设置套接字描述符,然后将QTcpSocket存储在一个挂起连接的内部列表中。最后发出newConnection()。
重新实现此函数,以在连接可用时更改服务器的行为。
如果此服务器使用QNetworkProxy,则socketDescriptor可能不能用于本机套接字函数,只能用于QTcpSocket::setSocketDescriptor()。
注意:如果在此方法的重新实现中创建了另一个套接字,则需要通过调用addPendingConnection()将其添加到挂起连接机制。
注意:如果您想要在另一个线程中处理一个新的QTcpSocket对象,那么您必须将socketDescriptor传递给另一个线程,并在那里创建QTcpSocket对象,然后使用它的setSocketDescriptor()方法。

作用说白了,就是,有此函数,然后你有自己的QTcpSocket,那么将这个socket描述符赋值到你的socket中,那么你就可以用这个描述符了

工程代码:

本文发布于:2024-02-04 05:20:54,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170700017852479.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

下一篇:vivado【3】
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23