網(wǎng)站首頁 編程語言 正文
復(fù)習(xí)的心態(tài)過一遍之前基礎(chǔ)的一些東西,Qt封裝了QTcpServer和QTcpSocket兩個(gè)類,其中QTcpServer繼承自QObject,通過listen()函數(shù)監(jiān)聽傳入的客戶端連接,當(dāng)Client連接上時(shí),QTcpServer會(huì)發(fā)出newConnection的信號(hào),在對(duì)應(yīng)的槽函數(shù)中使用nextPendingConnection()拿到連接的客戶端的句柄和信息。
而QTcpSocket則是讀寫數(shù)據(jù)的時(shí)候使用,過程很簡單。
服務(wù)器流程:listen->newConnection->nextPendingConnection->readAll/write
客戶端流程:connectToHost->waitForConnected->write/readAll
需要注意的是在使用網(wǎng)絡(luò)相關(guān)的類前,需要在pro文件加上QT += network
通信時(shí):
客戶端掉線時(shí):
QTcpServer服務(wù)器代碼(包含.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("服務(wù)端");
}
?
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;
? ? //發(fā)送數(shù)據(jù)
? ? 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
相關(guān)推薦
- 2022-03-26 C語言實(shí)現(xiàn)簡單的猜數(shù)字游戲_C 語言
- 2022-11-12 C語言大小端字節(jié)序存儲(chǔ)模式深入解讀_C 語言
- 2022-01-05 解決:啟動(dòng)Redis報(bào)錯(cuò):`Could not create server TCP listenin
- 2022-03-09 C++實(shí)現(xiàn)模擬shell命令行(代碼解析)_C 語言
- 2022-05-01 Qt實(shí)戰(zhàn)案例之如何利用QProcess類實(shí)現(xiàn)啟動(dòng)進(jìn)程_C 語言
- 2022-12-04 C#目錄和文件管理操作詳解_C#教程
- 2022-05-11 Nginx代理Redis哨兵主從配置
- 2022-07-26 二分搜索防止整形溢出
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支