網站首頁 編程語言 正文
復習的心態過一遍之前基礎的一些東西,Qt封裝了QTcpServer和QTcpSocket兩個類,其中QTcpServer繼承自QObject,通過listen()函數監聽傳入的客戶端連接,當Client連接上時,QTcpServer會發出newConnection的信號,在對應的槽函數中使用nextPendingConnection()拿到連接的客戶端的句柄和信息。
而QTcpSocket則是讀寫數據的時候使用,過程很簡單。
服務器流程:listen->newConnection->nextPendingConnection->readAll/write
客戶端流程:connectToHost->waitForConnected->write/readAll
需要注意的是在使用網絡相關的類前,需要在pro文件加上QT += network
通信時:
客戶端掉線時:
QTcpServer服務器代碼(包含.h和.cpp):
.h
#ifndef WIDGET_H
#define WIDGET_H
?
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
?
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
?
class Widget : public QWidget
{
? ? Q_OBJECT
?
public:
? ? Widget(QWidget *parent = nullptr);
? ? ~Widget();
?
protected slots:
? ? void onSendBtnClicked();
? ? void onNewClientConnected();
? ? void onRecvData();
? ? void onClientDisconnected();
?
private:
? ? void Init();
?
private:
? ? Ui::Widget *ui;
?
private:
? ? QTcpServer *_tcpServer;
? ? QTcpSocket *_tcpSocket;
};
#endif // WIDGET_H
.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#include <QDebug>
?
#define MyTcpPort 8886
?
Widget::Widget(QWidget *parent)
? ? : QWidget(parent)
? ? , ui(new Ui::Widget)
? ? ,_tcpServer(nullptr)
? ? ,_tcpSocket(nullptr)
{
? ? ui->setupUi(this);
?
? ? connect(this->ui->btn_send,&QPushButton::clicked,this,&Widget::onSendBtnClicked);
?
? ? Init();
?
? ? setWindowTitle("服務端");
}
?
Widget::~Widget()
{
? ? delete ui;
?
? ? if(_tcpSocket)
? ? {
? ? ? ? _tcpSocket->disconnect();
? ? ? ? _tcpSocket->abort();
? ? ? ? _tcpSocket->close();
? ? ? ? _tcpSocket->deleteLater();
? ? }
? ? if(_tcpServer)
? ? {
? ? ? ? _tcpServer->close();
? ? ? ? delete _tcpServer;
? ? }
}
?
void Widget::Init()
{
? ? _tcpSocket = new QTcpSocket;
? ? _tcpServer = new QTcpServer;
?
? ? int ret = _tcpServer->listen(QHostAddress::AnyIPv4,MyTcpPort);
? ? if(ret==0)
? ? {
? ? ? ? qDebug()<<"_tcpServer->listen is failied";
? ? ? ? return;
? ? }
? ? connect(_tcpServer,&QTcpServer::newConnection,this,&Widget::onNewClientConnected);
}
?
void Widget::onSendBtnClicked()
{
? ? if(!_tcpSocket) return;
?
? ? QString inputText = ui->inputEdit->text();
? ? if(inputText.isEmpty())
? ? ? ? return;
? ? //發送數據
? ? int ret = _tcpSocket->write(inputText.toStdString().c_str());
? ? if(ret<0)
? ? {
? ? ? ? qDebug()<<"write to client is failed!";
? ? }
}
?
void Widget::onNewClientConnected()
{
? ? if(_tcpServer->hasPendingConnections())
? ? {
? ? ? ? _tcpSocket = _tcpServer->nextPendingConnection();
? ? ? ? if(!_tcpSocket->isValid()) return;
? ? ? ? connect(_tcpSocket,&QTcpSocket::readyRead,this,
? ? ? ? ? ? ? ? &Widget::onRecvData);
? ? ? ? connect(_tcpSocket,&QTcpSocket::disconnected,this,
? ? ? ? ? ? ? ? &Widget::onClientDisconnected);
? ? }
}
?
void Widget::onRecvData()
{
? ? if(!_tcpSocket) return;
? ? QString recvData=_tcpSocket->readAll();
? ? qDebug()<<"recvData:"<<recvData;
?
? ? this->ui->recvEdit->append(recvData);
}
?
void Widget::onClientDisconnected()
{
? ? QString clientIp = _tcpSocket->peerAddress().toString();
? ? this->ui->recvEdit->append(clientIp+" is Drop line!");
}
QTcpClient客戶端代碼(包含.h和.cpp):
/.h
#ifndef WIDGET_H
#define WIDGET_H
?
#include <QWidget>
#include <QTcpSocket>
?
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
?
class Widget : public QWidget
{
? ? Q_OBJECT
?
public:
? ? Widget(QWidget *parent = nullptr);
? ? ~Widget();
?
private:
? ? void Init();
?
protected slots:
? ? void onSendBtnClicked();
? ? void onRecvData();
?
private:
? ? Ui::Widget *ui;
?
private:
? ? QTcpSocket *_tcpClient;
};
#endif // WIDGET_H
?
/.cpp
#include "widget.h"
#include "ui_widget.h"
?
#define MyTcpPort 8886
?
Widget::Widget(QWidget *parent)
? ? : QWidget(parent)
? ? , ui(new Ui::Widget),_tcpClient(nullptr)
{
? ? ui->setupUi(this);
?
? ? connect(this->ui->btn_send,&QPushButton::clicked,this,&Widget::onSendBtnClicked);
?
? ? Init();
?
? ? ?setWindowTitle("客戶端");
}
?
Widget::~Widget()
{
? ? delete ui;
?
? ? if(_tcpClient)
? ? {
? ? ? ? _tcpClient->close();
? ? ? ? _tcpClient->deleteLater();
? ? }
}
?
void Widget::Init()
{
? ? _tcpClient=new QTcpSocket;
? ? _tcpClient->abort();
? ? _tcpClient->connectToHost("127.0.0.1",MyTcpPort);
? ? if(!_tcpClient->waitForConnected(2000))
? ? {
? ? ? ? qDebug()<<"connect is failed!";
? ? ? ? return;
? ? }
? ? qDebug()<<"connect is successful";
? ? connect(_tcpClient,&QTcpSocket::readyRead,this,&Widget::onRecvData);
}
?
void Widget::onSendBtnClicked()
{
? ? if(!_tcpClient) return;
?
? ? QString wStr=ui->inputEdit->text();
?
? ? int ret = _tcpClient->write(wStr.toStdString().c_str());
? ? if(ret<0)
? ? {
? ? ? ? qDebug()<<"send data is failed";
? ? }
? ? qDebug()<<"send data is successful!";
}
?
void Widget::onRecvData()
{
? ? if(!_tcpClient) return;
?
? ? QString recvData= _tcpClient->readAll();
? ? ui->recvEdit->append(recvData);
? ? qDebug()<<"recvData:"<<recvData;
}
原文鏈接:https://blog.csdn.net/c_shell_python/article/details/123586179
相關推薦
- 2022-04-23 C語言實現字符串轉浮點函數的示例_C 語言
- 2022-06-17 關于Swagger優化的實戰記錄_實用技巧
- 2022-07-01 c++詳細講解構造函數的拷貝流程_C 語言
- 2022-05-19 Python學習之異常斷言詳解_python
- 2023-01-30 基于redis樂觀鎖實現并發排隊_Redis
- 2023-03-17 一文掌握git?push命令_相關技巧
- 2022-08-29 .NET?Core自定義配置文件_實用技巧
- 2022-11-30 C語言中順序棧和鏈棧的定義和使用詳解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支