QT TCP網(wǎng)絡(luò)編程——服務(wù)端的實(shí)現(xiàn)
溫馨提示:初來(lái)乍到,請(qǐng)多關(guān)照,文章如有不足,還請(qǐng)不吝賜教。本程序是仿照通訊助手(NetAssist.exe)進(jìn)行界面設(shè)計(jì)以及基本功能實(shí)現(xiàn)的,主要實(shí)現(xiàn)的功能有監(jiān)聽服務(wù)器端口、發(fā)送、接收數(shù)據(jù)。使用到的工具及編程語(yǔ)言為:visual studio 2015、QT、C++,其中代碼僅供參考
前言
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
視頻演示:
一、QT TCP服務(wù)器
在開始編寫代碼之前,首先要知道QT網(wǎng)絡(luò)編程需要用到兩個(gè)類:
1、QTcpServer:主要是實(shí)現(xiàn)服務(wù)器的端口監(jiān)聽。
2、QTcpSocket:套接字,消息的接收和發(fā)送。
以上兩個(gè)類是實(shí)現(xiàn)QT TCP服務(wù)器必不可少的,這與QT TCP客戶端用的只有QTcpSocket類,后面的文章會(huì)講到,此處不做過多贅述。
二、編程步驟
1.引入主要的庫(kù)
#include “qtcpserver.h”
#include “qtcpsocket.h”
#include “qnetworkinterface.h”
2.界面的設(shè)計(jì)
主要使用的是QT,拉取控件實(shí)現(xiàn)的:
3.具體實(shí)現(xiàn)步驟
3.1自動(dòng)獲取本機(jī)地址
如果是簡(jiǎn)單的使用QNetworkInterface::allAddresses()
,獲取到的IP集合中包含fff之類的數(shù)據(jù),所以就需要進(jìn)行篩選。篩選本地地址的主要思路如下:
1.IP地址的組成主要是數(shù)字;
2.IP地址的范圍主要是0.0.0.0~255.255.255.255之間(不細(xì)分);
3.IP字段都包含“.”;
4.IP字段以“.”劃分,有四段;
根據(jù)上面的思路,就可以在程序加載后,將本地合法的IP地址渲染到QComboBox中。
代碼如下(示例):
QStringList strList;
//得到本地IP的一個(gè)集合
QList<QHostAddress> ipList = QNetworkInterface::allAddresses();
//循環(huán)取出
for (int i = 0; i < ipList.size(); i++) {
QString ipStr = ipList[i].toString();
//ip地址在7~15之間
if (ipStr.size() < 7 || ipStr.size() > 15) {
continue;
}
QStringList ipStrList = ipStr.split(".");
//ip以.隔開 分為4組
if (ipStrList.size() != 4) {
continue;
}
for (int j = 0; j < ipStrList.size(); j++) {
int ipData = ipStrList[j].toInt();
try
{
//必須是數(shù)字 并且在0~255
if (ipData < 0 || ipData > 255) {
break;
}
}
catch (const std::exception&)
{
break;
}
}
strList.append(ipStr);
}
impl->ui.ipAddressBox->addItems(strList);
3.1 監(jiān)聽端口
開啟服務(wù)器端口服務(wù),建立QTcpServer對(duì)象,使用listen()方法就可以開啟指定的端口。
impl->tcpServer->listen(ipAddress, port)//監(jiān)聽指定IP 端口
服務(wù)器監(jiān)聽成功后,客戶即可通過指定的IP和端口連接到該服務(wù)器。服務(wù)器通過接收到newConnction()信號(hào)來(lái)判斷是否有客戶連接。
connect(impl->tcpServer, SIGNAL(newConnection()), this,SLOT(dealNewClientConnect()));
3.2 客戶連接
由于連接到服務(wù)器的客戶不止一個(gè),且服務(wù)器在發(fā)送數(shù)據(jù)時(shí),可以進(jìn)行群發(fā),也可以進(jìn)行單發(fā),所以在客戶連接到服務(wù)器時(shí),一定要先存儲(chǔ)好每個(gè)可戶端。這里使用的是構(gòu)造一個(gè)結(jié)構(gòu)體數(shù)據(jù)來(lái)存儲(chǔ)。
typedef struct {
QString clientIpAddress;
quint16 clientPort;
QTcpServer* sockServers;
QTcpSocket* tcpClients;
}ClientInfos;
有了結(jié)構(gòu)體后,當(dāng)有新的客戶連接到服務(wù)器時(shí),將該客戶端的IP即端口存儲(chǔ)下來(lái),代碼如下:
ClientInfos info;
//有新的連接
impl->tcpSocket = impl->tcpServer->nextPendingConnection();
info.tcpClients = impl->tcpSocket;
//獲取連接到服務(wù)器的客戶IP及地址
quint16 port = impl->tcpSocket->peerPort();
info.clientPort = port;
//IP
QHostAddress address = impl->tcpSocket->peerAddress();
QString ip = address.toString();
info.clientIpAddress = ip;
//添加到結(jié)構(gòu)體
impl->tcpSocketLists.append(info);
//更新combox
updateConnectBox();
impl->ui.receiveEdit->append(QString("[%1]# IP:%2,PORT:%3已連接").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(ip).arg(port)+"<br/>");
//當(dāng)客戶有數(shù)據(jù)過來(lái)時(shí),會(huì)產(chǎn)生readyRead信號(hào)
connect(impl->tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveData()));
//當(dāng)客戶自動(dòng)斷開連接時(shí),會(huì)產(chǎn)生disconnected信號(hào)
connect(impl->tcpSocket, SIGNAL(disconnected()), this, SLOT(dealDisconnected()));
3.3 讀寫數(shù)據(jù)
服務(wù)器的接收和發(fā)送數(shù)據(jù),主要是QTcpSocket提供的。
1.讀:
QByteArray arrs = impl->tcpSocketLists.at(i).tcpClients->readAll();
2.寫:
impl->tcpSocketLists.at(i).tcpClients->write(sendData.toLatin1());
3.4 客戶斷開連接
客戶端自動(dòng)斷開連接時(shí),會(huì)產(chǎn)生disconnected信號(hào)。這里主要是為了重新渲染連接到服務(wù)器的客戶端數(shù)量。
4 程序代碼鏈接
百度網(wǎng)盤鏈接分享
提取碼:6565
總結(jié)
提示:這里主要是自己寫這個(gè)程序過程的感悟,讀者可看可不看:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-441620.html
其實(shí)QT為TCP網(wǎng)絡(luò)編程提供了現(xiàn)成的類,只需要調(diào)用即可。主要還是界面功能的一些實(shí)現(xiàn),需要好好去琢磨。好了,QT服務(wù)器的實(shí)現(xiàn)就介紹在這了,有什么問題或想法,請(qǐng)私信我哦,下期再見!拜謝!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-441620.html
到了這里,關(guān)于QT TCP網(wǎng)絡(luò)編程——服務(wù)端的實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!