QT實現(xiàn)簡單TCP通信
本文實例為大家分享了QT實現(xiàn)簡單TCP通信的具體代碼,供大家參考,具體內(nèi)容如下
開發(fā)環(huán)境:win7
開發(fā)軟件:Qt5.5.0
下圖是實現(xiàn)效果
首先點擊客戶端的connect與服務(wù)器連接,連接成功后再服務(wù)器會顯示“成功連接”,然后在客戶端會顯示“成功與服務(wù)器建立連接”,然后我們就可以分別在服務(wù)器和客戶端向?qū)Ψ桨l(fā)送數(shù)據(jù)了。
1 TCP介紹
傳輸控制協(xié)議(TCP,Transmission Control Protocol)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。
在QT中的網(wǎng)絡(luò)編程的過程如下:服務(wù)器有兩個套接字,一個負(fù)責(zé)監(jiān)聽(QTcpServer),另一個負(fù)責(zé)通信(QTcpSocket),而客戶端只有一個負(fù)責(zé)通信的套接字(QTcpSocket)。
通信過程如下圖:
2 Tcp服務(wù)器實現(xiàn)
//監(jiān)聽套接字,指定父對象,讓其自動回收空間 tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::AnyIPv4, 6000);
當(dāng)有新的連接建立時,在服務(wù)器界面接收區(qū)處顯示客戶端地址和端口,并且等待數(shù)據(jù)發(fā)送過來,接收并顯示:
connect(tcpServer, &QTcpServer::newConnection, ? ? ? ? ? ? [=](){ ? ? ? ? ? ? ? ? //取出建立好連接的套接字 ? ? ? ? ? ? ? ? //cout << "有新的客戶端進(jìn)行連接"; ? ? ? ? ? ? ? ? tcpSocket = tcpServer->nextPendingConnection(); ? ? ? ? ? ? ? ? //獲取對方的IP和端口 ? ? ? ? ? ? ? ? QString ip = tcpSocket->peerAddress().toString(); ? ? ? ? ? ? ? ? quint16 port = tcpSocket->peerPort(); ? ? ? ? ? ? ? ? QString temp = QString("[%1:%2]:成功連接").arg(ip).arg(port); ? ? ? ? ? ? ? ? ? ? ? ? ui->textEditRead->setText(temp); ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? connect(tcpSocket, &QTcpSocket::readyRead, ? ? ? ? ? ? ? ? ? ? ? ? [=](){ ? ? ? ? ? ? ? ? ? ? ? ? ? ? //cout << "有數(shù)據(jù)從客戶端發(fā)過來"; ? ? ? ? ? ? ? ? ? ? ? ? ? ? //從通信套接字取出內(nèi)容 ? ? ? ? ? ? ? ? ? ? ? ? ? ? QByteArray array = tcpSocket->readAll(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ui->textEditRead->append(array); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ); ? ? ? ? ? ? } ? ? ? ? ? ? ); }
發(fā)送數(shù)據(jù):
void ServerWidget::on_buttonSend_clicked() { ? ? if(NULL == tcpSocket){ ? ? ? ? return; ? ? } ? ? //獲取編輯區(qū)內(nèi)容 ? ? QString str = ui->textEditWrite->toPlainText(); ? ? //給對方發(fā)送數(shù)據(jù)。使用套接字是tcpSocket ? ? tcpSocket->write(str.toUtf8().data()); }
點擊close按鈕,如果tcpSocket沒有分配內(nèi)存,則退出,否則斷開連接。
void ServerWidget::on_buttonClose_clicked() { ? ? if(NULL == tcpSocket){ ? ? ? ? return; ? ? } ? ? //主動和客戶端斷開連接 ? ? tcpSocket->disconnectFromHost(); ? ? tcpSocket->close(); ? ? tcpSocket = NULL; }
3 TCP客戶端實現(xiàn)
分配空間,指定父對象
tcpSocket = new QTcpSocket(this);
如果服務(wù)器發(fā)送連接成功,則客戶端顯示“成功與服務(wù)器建立連接”。
connect(tcpSocket, &QTcpSocket::connected, ? ? ? ? ? ? [=](){ ? ? ? ? ? ? ? ? ui->textEditRead->setText("成功與服務(wù)器建立連接"); ? ? ? ? ? ? } ? ? ? ? ? ? );
客戶端讀取數(shù)據(jù),并顯示在接收區(qū)
connect(tcpSocket, &QTcpSocket::readyRead, ? ? ? ? ? ? [=](){ ? ? ? ? ? ? ? ? //獲取服務(wù)器發(fā)送的內(nèi)容 ? ? ? ? ? ? ? ? QByteArray array = tcpSocket->readAll(); ? ? ? ? ? ? ? ? ui->textEditRead->append(array); ? ? ? ? ? ? } ? ? ? ? ? ? );
按下connect按鈕,主動與服務(wù)器建立連接
void ClientWidget::on_pushButtonConnect_clicked() { ? ? //獲取服務(wù)器ip和端口 ? ? QString ip = ui->lineEditIP->text(); ? ? quint16 port = ui->lineEditPort->text().toInt(); ? ? //主動和服務(wù)器建立連接 ? ? tcpSocket->connectToHost(QHostAddress(ip), port); }
按下send按鈕,發(fā)送數(shù)據(jù),轉(zhuǎn)成utf-8格式
void ClientWidget::on_pushButtonSend_clicked() { ? ? if(NULL == tcpSocket){ ? ? ? ? return; ? ? } ? ? //獲取編輯區(qū)內(nèi)容 ? ? QString str = ui->textEditWrite->toPlainText(); ? ? //給對方發(fā)送數(shù)據(jù),使用套接字是tcpSocket ? ? tcpSocket->write(str.toUtf8().data()); }
按下close關(guān)閉連接
void ClientWidget::on_pushButtonClose_clicked() { ? ? tcpSocket->disconnectFromHost(); ? ? tcpSocket->close(); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++中常見容器類的使用方法詳解(vector/deque/map/set)
C++中常見的容器類有vector、list、deque、map、set、unordered_map和unordered_set。下面將舉例直接說明各個容器的使用方法,希望對大家有所幫助2023-03-03OpenMP?Parallel?Construct的實現(xiàn)原理詳解
在本篇文章當(dāng)中我們將主要分析?OpenMP?當(dāng)中的?parallel?construct?具體時如何實現(xiàn)的,以及這個?construct?調(diào)用了哪些運行時庫函數(shù),并且詳細(xì)分析這期間的參數(shù)傳遞,需要的可以參考一下2023-01-01