首页 > 其他分享 >使用QT来写一个TCPsocket

使用QT来写一个TCPsocket

时间:2023-11-18 14:33:59浏览次数:33  
标签:QTcpServer TCPsocket QT 使用 socket 信号 QTcpSocket 连接 客户端

我们来了解一下什么是TCP的通讯小知识点,方便后续的理解

1. TCP的简单了解

由网上搜索的资料可知,tcp传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。

tcp通讯一定要经过三次握手才可以连接成功进行通讯;且,tcp通讯只能一对一进行连接;现在大多数通讯都是使用tcp协议,例如用于发送文件等。

QTcpSocket继承自QAbstractSocket,与QUdpSocket传输的数据报不同的是,QTcpSocket传输的是连续的数据流,尤其适合连续的数据传输,TCP一般分为客户端和服务端,即C/S (Client/Server模型)。

QTcpSocket代表了两个独立的数据流,一个用来读取数据,一个用来写入数据,分别采用QTcpSocket::read()及QTcpSocket::write()操作,读取数据前先调用QTcpSocket::bytesAvailable来确定已有足够的数据可用。

QTcpServer处理客户端的连接,可通过QTcpServer::listen()监听客户端发来的连接请求,每当有客户端连接时会发射newConnection()信号,QTcpSocket可用于读取客户端发来的数据报,亦可发送数据报。

注意:QTcpSocket被称为通信套接字;
QTcpServer被称为监听套接字。

1.1QTcpServer服务端建立

首先要在pro文件增加网络库,即QT += network

然后才是QTcpServer服务端的建立

QTcpServer server = new QTcpServer();

connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);//监听

if(!server->listen(QHostAddress::Any, 8000)) {

qDebug()<<server->errorString(); 

}```

创建server对象后先要监听客户端的连接,通过listen函数可以开启监听,但是需要指定的监听ip和端口号,其中ip可以使用QHostAddress::Any

QTcpServer当有新客户端连接时会发出QTcpServer::newConnection的信号,只需要关联到自定义的槽即可。

void MainWindow::server_New_Connect() {

//获取客户端连接
 auto socket_temp = server->nextPendingConnection();//根据当前新连接创建一个QTepSocket
 m_socket=socket_temp;//记录此连接用于后续数据读写
 //连接QTcpSocket的信号槽,以读取新数据
 QObject::connect(socket_temp, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
//当断开连接时发出的信号
 QObject::connect(socket_temp, &QTcpSocket::disconnected, this,&MainWindow::socket_Disconnected);
}

上述为一个新的接到的槽函数例子,利用nextPendingConnection获取到新的连接的socket,存储到此socket,并关联对应的信号。

主要有两个:接收到新的数据的信号以及连接断开的信号。

当连接断开可以响应信号槽机实现开后的操作。

1.2客户端的建立

客户端为主动连接方,不需要监听,直接建立QTcpServer就可以了。

m_socket = new QTcpSocket;
m_socket->connectToHost("127.0.0.1",80100,QTcpSocket::ReadWrite);
connect(m_socket,SIGNAL(connected()),this,SLOT(connected()));

上述例子使用的是信号槽方式等待连接成功,也可以使用阻塞方式:waitForConnected,等到接连成功才会执行后续代码,不需要建立新的槽函数。

通过connectToHost连接指定ip和端口,同时将socket的连接成功的信号与对应槽连接,当连接成功可以将自定义的标记位置为true,可进行相应的收发。

void MainWindow::connected() {
m_is_connected = true;
connect(this->socket,SIGNAL(readyRead()),this,SLOT(readyread())); //连接接收消息槽
QObject::connect(socket_temp,?&QTcpSocket::disconnected,?this,?&MainWindow::socket_Disconnected);//断开连接
}

当成功建立将接受和断开的信号进行connect

1.3信息收发

1.3.1阻塞收发

QT有提供阻塞收发以及连接、断开连接的函数:

virtual bool waitForConnected(int msecs = 30000)
virtual bool waitForDisconnected(int msecs = 30000)
virtual bool waitForBytesWritten(int msecs = 30000)
virtual bool waitForReadyRead(int msecs = 30000)

通过上述函数可以实现阻塞连接、断开连接、发送、接收数据内容

1.3.2不阻塞收发

无论客户端还是服务端只有在建立连接时有差异,后续的信息手法都相同

首先通过QTcpSocket::close()可以主动断开连接,无论客户端还是服务端都可以执行主动断开,通过readyRead()信号可以在接到信号时进行信息操作,在槽中执行QTcpSocket::readAll()可以读取缓冲区所有数据。

QTcpSocket::send()可发送信息,调用flush可立即发送缓冲区的数据,不需等待。


总结:1.服务端调用listen函数进行监听,是否有客户端与其进行连接;
2.客户端需要进行主动与客户端连接,调用connectToHost进行连接;
3.服务端:如果与客户端连接成功,服务器会触发newConnection信号;
4.客户端:如果与服务器连接成功,客户端会触发connected信号;
5.当断开连接,客户端的通信套接字会触发disconnected信号,服务器的通信套接字也会触发 disconnected信号;
6.服务器:触发newConnection信号后,必须在槽函数中实例化QTcpSocket对象;
7.服务端与客户端都是通过自己的通信套接字使用wirte函数进行发送信息;
8.服务端与客户端接收到对方发过来的消息时,都会触发readyRead信号,然后就可以在对应槽函数做接受处理;
9.服务端与客户端的断开都是使用通信套接字调用disconnectFromHost函数进行断开处理。

标签:QTcpServer,TCPsocket,QT,使用,socket,信号,QTcpSocket,连接,客户端
From: https://www.cnblogs.com/zongmeijiezuishuai/p/17840458.html

相关文章

  • Form表单组件封装和使用
    表单Form是中后台频繁使用的组件,以下是一个基于arcodesignvue组件库封装的表单组件。这个表单组件特点:所有配置都是直接继承组件库组件的props,无需其他文档可配置展开折叠支持响应式布局表单项支持动态隐藏插槽支持,自定义扩展组件库的良好支持,封装代码简洁优雅placeh......
  • 摩卡壶使用总结
    今天总结的摩卡壶使用:电磁灶/铝制摩卡壶 1200w档位,从冷炉子开机,5分钟离火关炉子放在隔热垫上,听到噗呲噗呲声音,就可以倒出来喝了摩卡壶放置冷却30分钟之后才能打开清洗粉碗一定清洗干净,发现有堵住的地方一定要疏通 ......
  • Python如何使用Networkx实现复杂的人物关系图?
    (Python如何使用Networkx实现复杂的人物关系图?)1简单引入日常工作、生活中我们经常会遇到一些复杂的事务关系,比如人物关系,那如何才能清楚直观的看清楚这些任务关系呢?比如我们从网上搜索1个人物关系图,大家看看:声明:以下图片来源于网络,如果涉及版权问题,请联系作者删除。本文仅......
  • 打工笔记-------------layui弹出窗使用
    //初体验//layer.alert('内容')//第三方扩展皮肤//layer.alert('内容',{//icon:1,//skin:'layer-ext-moon'//该皮肤由layer.seaning.com友情扩展。关于皮肤的扩展规则,去这里查阅//})//询问框//layer.confirm('您是如何看待前端开发?',{//btn:['重要','奇葩'......
  • 使用 ABAP + OLE 消费 Windows DLL 文件里的代码和服务
    在SAPABAP中,我们可以使用OLE(ObjectLinkingandEmbedding)技术来实现对WindowsDLL文件的代码和服务的消费。以下是一个详细的解决方案:首先,我们需要明确OLE技术在ABAP中的应用。OLE是由微软开发的一种技术,它允许对象(即应用程序功能)被嵌入到其他应用程序中。在ABA......
  • 使用OpenAI Assistants三分钟搭建个人知识库AI助手网站
    Assistants介绍             随着OpenAI将Assistants助手API对外发布,我们搭建个人知识库变的如此简单。开发者将自己的应用通过AssistantsAPI与OpenAI对接,就可以让每一位客户拥有不一般体验的个人知识库。由于Assistants相关API有30+,本文只列举完成一个最小功能......
  • null 不好,我真的推荐你使用 Optional
    "Null很糟糕."-DougLea。DougLea是一位美国的计算机科学家,他是Java平台的并发和集合框架的主要设计者之一。他在2014年的一篇文章中说过:“Nullsucks.”1,意思是null很糟糕。他认为null是一种不明确的表示,它既可以表示一个值不存在,也可以表示一个值未知,也可以表示......
  • junit简单使用(入门)
    @目录......
  • Log4j入门使用(什么是日志? 为什么要使用1og4j)
    @目录......
  • 5 步在 Ubuntu22 上使用 C++20
    1.安装build-essentialsudoaptinstallbuild-essential安装完检查/usr/bin/下是否有gcc,g++,gcc-11,g++11.2.添加ppa源sudoadd-apt-repositoryppa:ubuntu-toolchain-r/test3.安装gcc-13和g++-13sudoapt-getinstallgcc-13sudoapt-getinstallg++-......