Qt實(shí)現(xiàn)TCP網(wǎng)絡(luò)編程
本文實(shí)例為大家分享了Qt實(shí)現(xiàn)TCP網(wǎng)絡(luò)編程的具體代碼,供大家參考,具體內(nèi)容如下
1.Qt中的TCP客戶(hù)端編程

Qt中的TCP客戶(hù)端編程:
對(duì)于Qt編程而言,網(wǎng)絡(luò)只是數(shù)據(jù)傳輸?shù)耐ǖ?/strong>
Qt提供了QTcpSocket類(lèi)(封裝了TCP協(xié)議細(xì)節(jié))
將QTcpSocket的對(duì)象當(dāng)做黑盒使用,進(jìn)行數(shù)據(jù)收發(fā)

QTcpSocket的使用方式:
1.連接服務(wù)端主機(jī)(connectToHost())
2.發(fā)送數(shù)據(jù)/接受數(shù)據(jù)(write()/read())
3.關(guān)閉連接(close())
QTcpSocket的注意事項(xiàng):
默認(rèn)情況下,QTcpSocket使用異步編程的方式:
操作完成后立即返回
通過(guò)發(fā)送信號(hào)的方式返回操作結(jié)果
QTcpSocket提供了輔助函數(shù),可完成同步編程的方式
waitForConnected()/waitForDisconnected()
waitForBytesWritten()/waitForReadyread()
QTcpSocket的同步編程:

編程實(shí)驗(yàn):同步編程
#include <QCoreApplication>
#include <QTcpSocket>
#include <QDebug>
#include <QThread>
void SyncClientDemo()
{
? ? QTcpSocket client;
? ? char buf[256] = {0};
? ? client.connectToHost("127.0.0.1",8080);
? ? qDebug() << "Connected:" << client.waitForConnected();
? ? qDebug() << "Send Bytes:" << client.write("CKY");
? ? qDebug() << "Send Status:" << client.waitForBytesWritten();
? ? qDebug() << "Data Avilable:" << client.waitForReadyRead();
? ? qDebug() << "Received Bytes:" << client.read(buf, sizeof(buf));
? ? qDebug() << "Received Data:" << buf;
? ? QThread::sleep(5000);
? ? client.close();
? ? client.waitForDisconnected();
}
int main(int argc, char *argv[])
{
? ? QCoreApplication a(argc, argv);
? ? SyncClientDemo();
? ? return a.exec();
}QTcpSocket的異步編程:
QTcpSocket對(duì)象通過(guò)發(fā)送信號(hào)的方式返回操作結(jié)果
可以在程序中將對(duì)應(yīng)的信號(hào)連接到槽函數(shù),獲取結(jié)果
在GUI應(yīng)用程序中通常使用QTcpSocket的異步方式
QTcpSocket中的關(guān)鍵信號(hào):
connected():成功連接遠(yuǎn)端主機(jī)
disconnected():遠(yuǎn)端主機(jī)斷開(kāi)連接
readyRead():遠(yuǎn)程數(shù)據(jù)到達(dá)本機(jī)
bytesWritten(qint64):數(shù)據(jù)成功發(fā)送至系統(tǒng)(OS)
編程實(shí)驗(yàn):QTcpSocket異步編程
#include "clientdemo.h"
#include <QDebug>
#include <QHostAddress>
ClientDemo::ClientDemo(QObject* parent) : QObject(parent)
{
? ? connect(&m_client, SIGNAL(connected()), this, SLOT(onConnected()));
? ? connect(&m_client, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
? ? connect(&m_client, SIGNAL(readyRead()), this, SLOT(onDataReady()));
? ? connect(&m_client, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
}
void ClientDemo::onConnected()
{
? ? qDebug() << "onConnected()";
? ? qDebug() << "Local Address:" << m_client.localAddress();
? ? qDebug() << "Loacl Port:" << m_client.localPort();
}
void ClientDemo::onDisconnected()
{
? ? qDebug() << "onDiecennected()";
}
void ClientDemo::onDataReady()
{
? ? char buf[256] = {0};
? ? qDebug() << "onDataReady:" << m_client.read(buf, sizeof(buf));
? ? qDebug() << "Data:" << buf;
}
void ClientDemo::onBytesWritten(qint64 bytes)
{
? ? qDebug() << "onBytesWritten" << bytes;
}
void ClientDemo::connectTo(QString ip, int port)
{
? ? m_client.connectToHost(ip, port);
}
qint64 ClientDemo::send(const char* data, int len)
{
? ? return m_client.write(data, len);
}
qint64 ClientDemo::available()
{
? ? return m_client.bytesAvailable();
}
void ClientDemo::close()
{
? ? m_client.close();
}1.Qt中的TCP服務(wù)端編程
網(wǎng)絡(luò)中的服務(wù)端:
服務(wù)端是為客戶(hù)端服務(wù)的,服務(wù)的內(nèi)容諸如向客戶(hù)端提供資源,保存客戶(hù)端數(shù)據(jù),為客戶(hù)端提供功能接口,等
Client/Server軟件架構(gòu)簡(jiǎn)介

特點(diǎn);
服務(wù)端被動(dòng)接受連接(服務(wù)端無(wú)法主動(dòng)連接客戶(hù)端)
服務(wù)端必須公開(kāi)網(wǎng)絡(luò)地址(容易受到攻擊)
在職責(zé)上:
客戶(hù)端傾向于處理用于交互及體驗(yàn)(GUI)
服務(wù)端傾向于用戶(hù)數(shù)據(jù)的組織和存儲(chǔ)(數(shù)據(jù)處理)
B/S網(wǎng)絡(luò)結(jié)構(gòu)是什么?
Browser/Server軟件架構(gòu)簡(jiǎn)介
B/S是一種特殊的C/S網(wǎng)絡(luò)架構(gòu)
B/S中的客戶(hù)端統(tǒng)一使用瀏覽器(Browser)
B/S中的客戶(hù)端GUI通常采用HTML進(jìn)行開(kāi)發(fā)
B/S中的客戶(hù)端與服務(wù)端通常采用http協(xié)議進(jìn)行通信
Qt中的TCP服務(wù)端編程:
Qt提供了QTcpServer類(lèi)
將QTcpServer的對(duì)象當(dāng)做黑盒使用,進(jìn)行連接監(jiān)聽(tīng)
每一個(gè)連接生成一個(gè)QTcpSocket對(duì)象進(jìn)行通信

QTcpServer的使用方式:
監(jiān)聽(tīng)本機(jī)地址的端口(listen())
通過(guò)信號(hào)通知客戶(hù)端連接(newConnection())
獲取QTcpSocket通信對(duì)象(nextPendingConnection())
停止監(jiān)聽(tīng)(close())
QTcpServer的注意事項(xiàng):
用于處理客戶(hù)端連接,不進(jìn)行具體通信
監(jiān)聽(tīng)的端口只用于響應(yīng)連接請(qǐng)求
監(jiān)聽(tīng)到連接后,生成QTcpSocket對(duì)象與客戶(hù)端通信
Client/Server交互流程:

編程實(shí)驗(yàn):QServerSocket編程
#include "serverdemo.h"
#include "QHostAddress"
#include <QDebug>
#include <QTcpServer>
#include <QObjectList>
ServerDemo::ServerDemo(QObject* parent) : QObject(parent)
{
? ? connect(&m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
void ServerDemo::onNewConnection()
{
? ? qDebug() << "onNewConnection";
? ? QTcpSocket* tcp = m_server.nextPendingConnection();
? ? connect(tcp, SIGNAL(connected()), this, SLOT(onConnected()));
? ? connect(tcp, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
? ? connect(tcp, SIGNAL(readyRead()), this, SLOT(onDataReady()));
? ? connect(tcp, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
}
bool ServerDemo::start(int port)
{
? ? bool ret = true;
? ? if(!m_server.isListening())
? ? {
? ? ? ? ret = m_server.listen(QHostAddress("127.0.0.1", port));
? ? }
? ? return ret;
}
void ServerDemo::stop()
{
? ? if(m_server.isListening())
? ? {
? ? ? ? m_server.close();
? ? }
}
void ServerDemo::onConnected()
{
? ? QTcpServer* tcp = dynamic_cast<QTcpServer*>(sender());
? ? if(tcp != NULL)
? ? {
? ? ? ? qDebug() << "onConnected()";
? ? ? ? qDebug() << "Local Address:" << tcp->localAddress();
? ? ? ? qDebug() << "Loacl Port:" << tcp->localPort();
? ? }
}
void ServerDemo::onDisconnected()
{
? ? qDebug() << "onDiecennected()";
}
void ServerDemo::onDataReady()
{
? ? QTcpServer* tcp = dynamic_cast<QTcpServer*>(sender());
? ? char buf[256] = {0};
? ? if(tcp != NULL)
? ? {
? ? ? ? qDebug() << "onDataReady:" << tcp->read(buf, sizeof(buf));
? ? ? ? qDebug() << "Data:" << buf;
? ? }
}
void ServerDemo::onBytesWritten(qint64 bytes)
{
? ? qDebug() << "onBytesWritten" << bytes;
}
ServerDemo::~ServerDemo()
{
? ? const QObjectList& list = m_server.children();
? ? for(int i = 0; i < list.length(), i++)
? ? {
? ? ? ? QTcpSocket* tcp = dynamic_cast<QTcpSocket*>(list[i]);
? ? ? ? if(tcp != NULL)
? ? ? ? {
? ? ? ? ? ? tcp->close();
? ? ? ? }
? ? }
}以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Qt5.9.5 隨機(jī)轉(zhuǎn)盤(pán)小項(xiàng)目的實(shí)現(xiàn)示例
本文主要介紹了Qt5.9.5隨機(jī)轉(zhuǎn)盤(pán)小項(xiàng)目的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
C語(yǔ)言實(shí)現(xiàn)紙牌游戲(小貓釣魚(yú))
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)紙牌游戲,小貓釣魚(yú)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
C++多線(xiàn)程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶(hù)端通信
通訊建立后首先由服務(wù)器端發(fā)送消息,客戶(hù)端接收消息;接著客戶(hù)端發(fā)送消息,服務(wù)器端接收消息,實(shí)現(xiàn)交互發(fā)送消息。本文主要介紹了C++多線(xiàn)程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶(hù)端通信,感興趣的可以了解一下2021-05-05
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿(mǎn)
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿(mǎn)的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法,涉及系統(tǒng)函數(shù)atoi()函數(shù)的使用技巧,需要的朋友可以參考下2014-12-12
重啟后nvidia-smi命令不可執(zhí)行出現(xiàn)“Make?sure?that?the?latest?NVIDIA?
這篇文章主要介紹了重啟后nvidia-smi命令不可執(zhí)行,出現(xiàn)“Make?sure?that?the?latest?NVIDIA?driver?is?installed?and?running.”問(wèn)題,本文給大家分享最新完美解決方法,需要的朋友可以參考下2022-12-12
關(guān)于C/C++中typedef的定義與用法總結(jié)
在C還是C++代碼中,typedef都使用的很多,在C代碼中尤其是多,typedef與#define有些相似,其實(shí)是不同的,特別是在一些復(fù)雜的用法上,需要的朋友可以參考下2012-12-12
C++?計(jì)算時(shí)間差的五種方法小結(jié)
本文主要介紹了C++?計(jì)算時(shí)間差的五種方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
C++ 中CListCtrl的每個(gè)項(xiàng)都顯示不同的提示信息
這篇文章主要介紹了C++ 中CListCtrl的每個(gè)項(xiàng)都顯示不同的提示信息的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09

