日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

qt tcp通信_Qt之网络编程TCP通信

發布時間:2024/9/19 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qt tcp通信_Qt之网络编程TCP通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊上方“Qt學視覺”,選擇“星標”公眾號重磅干貨,第一時間送達

想要學習的同學們還請認真閱讀每篇文章,相信你一定會有所收獲

TCP通信概述

? ?TCP(Transmission Control Protocol)是一種被大多數 Internet 網絡協議(如 HTTP 和 FTP)用于 數據傳輸的低級網絡協議,它是可靠的、面向流、面向連接的傳輸協議,特別適合用于連續數據傳輸。

? ?TCP通信必須先建立TCP連接,通信端分為客戶端和服務器端。

? ?Qt提供 QTcpSocket類和QTcpServer類用于建立TCP通信應用程 TCP Client 序。

? ?服務器端程序必須使用QTcpServer用于端口監聽,建 立服務器;

? ?QTcpSocket用于建立連接后使用套接字(Socket) 進行通信。

? ?QTcpServer是從QObject繼承的類,它主要用于服務器端建立網絡監聽,創建網絡Socket連 接。QTcpServer類的主要接口函數見表

  • void close()

    • 關閉服務器,停止網絡監聽

  • bool listen()

    • 在給定IP地址和端口上開始監聽,若成功就返回true

  • bool isListening()

    • 返回true表示服務器處于監聽狀態

  • QTcpSocket * nextPendingConnection()

    • 返回下一個等待接入的連接

  • QHostAddress serverAddress()

    • 如果服務器處于監聽狀態,返回服務器地址

  • quint 16 serverPort()

    • 如果服務器處于監聽狀態,返回服務器監聽端口

  • bool waitForNewConnection()

    • 以阻塞方式等待新的連接 信號

  • void acceptError( QAbstractSocket::SocketError socketError)

    • 當接受一個新的連接發生錯誤時發射此信號,參數 socketError描述了錯誤信息

  • void newConnection()

    • ?當有新的連接時發射此信號

  • void incomingConnection(qintptr socketDescriptor)

    • 當有一個新的連接可用時,QTcpServer內部調用此函數,創 建一個QTcpSocket對象,添加到內部可用新連接列表,然 后發射newConnection()信號。用戶若從QTcpServer繼承定 義類,可以重定義此函數,但必須調用 addPendingConnection()

  • void addPendingConnection(QTcpSocket ?socket)

    • 由 incomingConnection()調用,將創建的 QTcpSocket 添加到 內部新可用連接列表

?? ?服務器端程序首先需要用QTcpServendisten()開始服務器端監聽,可以指定監聽的IP地址和 端口,一般一個服務程序只監聽某個端口的網絡連接。

?? ?當有新的客戶端接入時,QTcpServer內部的incomingConnection()函數會創建一個與客戶端連 接的QTcpSocket對象,然后發射信號newConnection()。在newConnection()信號的槽函數中,可以用nextPendingConnection()接受客戶端的連接,然后使用QTcpSocket與客戶端通信。?? ??? ?

?? ?所以在客戶端與服務器建立TCP連接后,具體的數據通信是通過QTcpSocket完成的。QTcpSocket類提供了 TCP協議的接口,可以用QTcpSocket類實現標準的網絡通信協議如POP3、 SMTP和NNTP,也可以設計自定義協議。?

?? ?QTcpSocket是從QIODevice間接繼承的類,所以具有流讀寫的功能

?? ?

QTcpSocket類除了構造函數和析構函數,其他函數都是從QAbstractSocket繼承或重定義的。QAbstractSocket用于TCP通信的主要接口函數見表

  • void connectToHost(QHostAddress?&address, quint 16 port,)

    • 以異步方式連接到指定IP地址和端口的TCP服務器,連接成功? 后會發射connected()信號

  • void disconnectFromHost()

    • 斷開socket,關閉成功后發射disconnected()信號

  • bool waitForConnected()

    • 等待直到建立socket連接

  • bool waitForDisconnected()

    • 等待直到斷開socket連接

  • QHostAddress localAddress()

    • 返回本socket的地址

  • quint 16 localPort()

    • 返回本socket的端口

  • QHostAddress peerAddress()

    • 在已連接狀態下,返回對方socket的地址

  • QString peerName()

    • 返回connectToHost()連接到的對方的主機名

  • quintl6 peerPort()

    • 在已連接狀態下,返回對方socket的端口

  • qint64 readBufferSize()

    • 返回內部讀取緩沖區的大小,該大小決定了 read()和 readAII()函數能讀出的數據的大小

  • void setReadBufferSize(qint64 size)

    • 設置內部讀取緩沖區大小

  • qint64 bytesAvailable()

    • 返回需要讀取的緩沖區的數據的字節數

  • bool canReadLine()

    • 如果有行數據要從socket緩沖區讀取,就返回true

  • SocketState state()

    • 返回socket當前的狀態

  • void connected()

    • connectToHost()成功連接到服務器后發射此信號

  • void disconnected()

    • 當socket斷開連接后發射此信號

  • void error(QAbstractSocket::SocketError socketError)

    • 當socket發生錯誤時發射此信號

  • void hostFound()

    • 調用connectToHost()找到主機后發射此信號

  • void stateChanged(QAbstractSocket::SocketState socketState)

    • 當 socket的狀態變化時發射此信號,參數socketState表示了socket 當前的狀態

  • void readyRead()

    • 當緩沖區有新數據需要讀取時發射此信號,在此信號的槽函數里 讀取緩沖區的數據

?? ?TCP客戶端使用QTcpSocket與TCP服務器建立連接并通信

?? ?客戶端的QTcpSocket實例首先通過connectToHost()嘗試連接到服務器,需要指定服務器的IP地址和端口.connectToHost()是異步方式連接服務器,不會阻塞程序運行,連接后發射connected()信號。

?? ?如果需要使用阻塞方式連接服務器,則使用waitForConnected()函數阻塞程序運行,直到連接 成功或失敗。例如:?

socket->connectToHost("192.168.1.100", 1340); if (socket->waitForConnected(1000)) qDebug("Connected!");

?? ?與服務器端建立socket連接后,就可以向緩沖區寫數據或從接收緩沖區讀取數據,實現數據的通信。當緩沖區有新數據進入時,會發射readyRead()信號,一般在此信號的槽函數里讀取緩沖區數據。

?? ?QTcpSocket是從QIODevice間接繼承的,所以可以使用流數據讀寫功能。—個QTcpSocket 實例既可以接收數據也可以發送數據,且接收與發射是異步工作的,有各自的緩沖區。?

?? ?作為演示TCP通信的實例,創建了一個TCPClient程序和一個TCPServer程序

TCPServer程序具有如下的功能:?

?? ??根據指定IP地址(本機地址)和端口打開網絡監聽,有客戶端連接時創建socket連接;?

?? ??采用基于行的數據通信協議,可以接收客戶端發來的消息,也可以向客戶端發送消息;?

?? ??在狀態欄顯示服務器監聽狀態和socket的狀態。?

頭文件

#pragma once#include #include "Ui_QGuiTcpServer.h"#include #include #include class QGuiTcpServer : public QMainWindow{ Q_OBJECTpublic: QGuiTcpServer(QWidget *parent = Q_NULLPTR); ~QGuiTcpServer();private slots: void actStart_triggered();//開始監聽 void actStop_triggered(); void actHostInfo_triggered(); void actClear_triggered(); void btnSend_clicked(); void onNewConnection(); void onSocketStateChange(QAbstractSocket::SocketState socketState); void onClientConnected(); //Client Socket connected void onClientDisconnected();//Client Socket disconnected void onSocketReadyRead();//讀取socket傳入的數據private: Ui::QTcpServer ui;protected: void closeEvent(QCloseEvent* event);private: QLabel* m_pLabListen;//狀態欄標簽 QLabel* m_pLabSocketState;//狀態欄標簽 QTcpServer* m_pTcpServer;//tcp服務器 QTcpSocket* m_pTcpSocket;//tcp通信的Socket QString getLocalIP();//獲取本機IP地址};

源文件

#include "QGuiTcpServer.h"#include #include #pragma execution_character_set("utf-8")QGuiTcpServer::QGuiTcpServer(QWidget *parent) : QMainWindow(parent){ ui.setupUi(this); m_pLabListen = new QLabel("監聽狀態:"); m_pLabListen->setMinimumWidth(150); ui.statusBar->addWidget(m_pLabListen); m_pLabSocketState = new QLabel("狀態:"); m_pLabSocketState->setMinimumWidth(200); ui.statusBar->addWidget(m_pLabSocketState); QString localIP = getLocalIP();//本機IP setWindowTitle(windowTitle() + "----本機IP:" + localIP); ui.comboIP->addItem(localIP); m_pTcpServer = new QTcpServer(this); connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection())); connect(ui.actStart, SIGNAL(triggered()), this, SLOT(actStart_triggered())); connect(ui.actStop, SIGNAL(triggered()), this, SLOT(actStop_triggered())); connect(ui.actHostInfo, SIGNAL(triggered()), this, SLOT(actHostInfo_triggered())); connect(ui.actClear, SIGNAL(triggered()), this, SLOT(actClear_triggered())); connect(ui.btnSend, SIGNAL(clicked()), this, SLOT(btnSend_clicked()));}QGuiTcpServer::~QGuiTcpServer(){}//開始監聽void QGuiTcpServer::actStart_triggered(){ QString IP = ui.comboIP->currentText();//IP地址 quint16 port = ui.spinPort->value();//端口 QHostAddress addr(IP); m_pTcpServer->listen(addr, port);// //m_pLabListen->listen(QHostAddress::LocalHost,port);// Equivalent to QHostAddress("127.0.0.1"). ui.plainTextEdit->appendPlainText("**開始監聽..."); ui.plainTextEdit->appendPlainText("**服務器地址:"+ m_pTcpServer->serverAddress().toString()); ui.plainTextEdit->appendPlainText("**服務器端口:"+ QString::number(m_pTcpServer->serverPort())); ui.actStart->setEnabled(false); ui.actStop->setEnabled(true); m_pLabListen->setText("監聽狀態:正在監聽");}void QGuiTcpServer::actStop_triggered(){ if (m_pTcpServer->isListening()) //tcpServer正在監聽 { m_pTcpServer->close();//停止監聽 ui.actStart->setEnabled(true); ui.actStop->setEnabled(false); m_pLabListen->setText("監聽狀態:已停止監聽"); }}void QGuiTcpServer::actHostInfo_triggered(){ QString hostName = QHostInfo::localHostName();//本地主機名 ui.plainTextEdit->appendPlainText("本機主機名:" + hostName + "\n"); QHostInfo hostInfo = QHostInfo::fromName(hostName); QList addList = hostInfo.addresses();// if (!addList.isEmpty()) { for (int i = 0; i < addList.count(); i++) { QHostAddress aHost = addList.at(i); if (QAbstractSocket::IPv4Protocol == aHost.protocol()) { QString IP = aHost.toString(); ui.plainTextEdit->appendPlainText("本機IP地址:" + aHost.toString()); if (ui.comboIP->findText(IP) < 0) ui.comboIP->addItem(IP); } } }}void QGuiTcpServer::actClear_triggered(){ ui.plainTextEdit->clear();}void QGuiTcpServer::btnSend_clicked(){ QString msg = ui.editMsg->text(); ui.plainTextEdit->appendPlainText("[out] " + msg); ui.editMsg->clear(); ui.editMsg->setFocus(); QByteArray str = msg.toUtf8(); str.append('\n');//添加一個換行符 m_pTcpSocket->write(str);}void QGuiTcpServer::onNewConnection(){ m_pTcpSocket = m_pTcpServer->nextPendingConnection(); //創建socket connect(m_pTcpSocket, SIGNAL(connected()), this, SLOT(onClientConnected())); onClientConnected(); connect(m_pTcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected())); connect(m_pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState))); onSocketStateChange(m_pTcpSocket->state()); connect(m_pTcpSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));}void QGuiTcpServer::onSocketStateChange(QAbstractSocket::SocketState socketState){ switch (socketState) { case QAbstractSocket::UnconnectedState: m_pLabSocketState->setText("scoket狀態:UnconnectedState"); break; case QAbstractSocket::HostLookupState: m_pLabSocketState->setText("scoket狀態:HostLookupState"); break; case QAbstractSocket::ConnectingState: m_pLabSocketState->setText("scoket狀態:ConnectingState"); break; case QAbstractSocket::ConnectedState: m_pLabSocketState->setText("scoket狀態:ConnectedState"); break; case QAbstractSocket::BoundState: m_pLabSocketState->setText("scoket狀態:BoundState"); break; case QAbstractSocket::ClosingState: m_pLabSocketState->setText("scoket狀態:ClosingState"); break; case QAbstractSocket::ListeningState: m_pLabSocketState->setText("scoket狀態:ListeningState"); }}//客戶端接入時void QGuiTcpServer::onClientConnected(){ ui.plainTextEdit->appendPlainText("**client socket connected"); ui.plainTextEdit->appendPlainText("**peer address:" + m_pTcpSocket->peerAddress().toString()); ui.plainTextEdit->appendPlainText("**peer port:" + QString::number(m_pTcpSocket->peerPort()));}//客戶端斷開連接時void QGuiTcpServer::onClientDisconnected(){ ui.plainTextEdit->appendPlainText("**client socket disconnected"); m_pTcpSocket->deleteLater();}//讀取緩沖區行文本void QGuiTcpServer::onSocketReadyRead(){ while (m_pTcpSocket->canReadLine()) ui.plainTextEdit->appendPlainText("[in] " + m_pTcpSocket->readLine());}//關閉窗口時停止監聽void QGuiTcpServer::closeEvent(QCloseEvent* event){ if (m_pTcpServer->isListening()) m_pTcpServer->close();;//停止網絡監聽 event->accept();}//獲取本機IP地址QString QGuiTcpServer::getLocalIP(){ QString hostName = QHostInfo::localHostName();//本機主機名 QHostInfo hostInfo = QHostInfo::fromName(hostName); QString localIP = ""; QList addList = hostInfo.addresses();// if (!addList.isEmpty()) { for (int i = 0; i < addList.count(); i++) { QHostAddress aHost = addList.at(i); if (QAbstractSocket::IPv4Protocol == aHost.protocol()) { localIP = aHost.toString(); break; } } } return localIP;}

TCPClient程序程序具有如下的功能:

?? ??通過IP地址和端口號連接到服務器;?

?? ??采用基于行的數據通信協議,與服務器端收發消息:?

?? ??處理QTcpSocket的StateChange()信號,在狀態欄顯示socket的狀態。

頭文件

#pragma once#include #include "ui_QGuiTcpClient.h"#include #include class QGuiTcpClient : public QMainWindow{ Q_OBJECTpublic: QGuiTcpClient(QWidget *parent = Q_NULLPTR); ~QGuiTcpClient();private slots: //自定義槽函數 void onConnected(); void onDisconnected(); void onSocketStateChange(QAbstractSocket::SocketState socketState); void onSocketReadyRead();//讀取socket傳入的數據 void actConnect_triggered(); void actDisconnect_triggered(); void actClear_triggered(); void btnSend_clicked();private: Ui::QGuiTcpClient ui;protected: void closeEvent(QCloseEvent* event);private: QTcpSocket* m_pTcpClient; //socket QLabel* m_pLabSocketState;//狀態欄標簽 QString getLocalIP();//獲取本機IP地址};

源文件

#include "QGuiTcpClient.h"#include #include #pragma execution_character_set("utf-8")QGuiTcpClient::QGuiTcpClient(QWidget* parent) : QMainWindow(parent){ ui.setupUi(this); m_pTcpClient = new QTcpSocket(this); //創建socket變量 m_pLabSocketState = new QLabel("Socket狀態:");//狀態欄標簽 m_pLabSocketState->setMinimumWidth(250); ui.statusBar->addWidget(m_pLabSocketState); QString localIP = getLocalIP();//本機IP this->setWindowTitle(this->windowTitle() + "----本機IP:" + localIP); ui.comboServer->addItem(localIP); connect(m_pTcpClient, SIGNAL(connected()), this, SLOT(onConnected())); connect(m_pTcpClient, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connect(m_pTcpClient, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState))); connect(m_pTcpClient, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead())); connect(ui.actConnect, SIGNAL(triggered()), this, SLOT(actConnect_triggered())); connect(ui.actDisconnect, SIGNAL(triggered()), this, SLOT(actDisconnect_triggered())); connect(ui.actClear, SIGNAL(triggered()), this, SLOT(actClear_triggered())); connect(ui.btnSend, SIGNAL(clicked()), this, SLOT(btnSend_clicked()));}QGuiTcpClient::~QGuiTcpClient(){}void QGuiTcpClient::onConnected(){ ui.plainTextEdit->appendPlainText("**已連接到服務器"); ui.plainTextEdit->appendPlainText("**peer address:" + m_pTcpClient->peerAddress().toString()); ui.plainTextEdit->appendPlainText("**peer port:" + QString::number(m_pTcpClient->peerPort())); ui.actConnect->setEnabled(false); ui.actDisconnect->setEnabled(true);}void QGuiTcpClient::onDisconnected(){ ui.plainTextEdit->appendPlainText("**已斷開與服務器的連接"); ui.actConnect->setEnabled(true); ui.actDisconnect->setEnabled(false);}void QGuiTcpClient::onSocketStateChange(QAbstractSocket::SocketState socketState){ switch (socketState) { case QAbstractSocket::UnconnectedState: m_pLabSocketState->setText("scoket狀態:UnconnectedState"); break; case QAbstractSocket::HostLookupState: m_pLabSocketState->setText("scoket狀態:HostLookupState"); break; case QAbstractSocket::ConnectingState: m_pLabSocketState->setText("scoket狀態:ConnectingState"); break; case QAbstractSocket::ConnectedState: m_pLabSocketState->setText("scoket狀態:ConnectedState"); break; case QAbstractSocket::BoundState: m_pLabSocketState->setText("scoket狀態:BoundState"); break; case QAbstractSocket::ClosingState: m_pLabSocketState->setText("scoket狀態:ClosingState"); break; case QAbstractSocket::ListeningState: m_pLabSocketState->setText("scoket狀態:ListeningState"); }}void QGuiTcpClient::onSocketReadyRead(){ while (m_pTcpClient->canReadLine()) ui.plainTextEdit->appendPlainText("[in] " + m_pTcpClient->readLine());}void QGuiTcpClient::actConnect_triggered(){ QString addr = ui.comboServer->currentText(); quint16 port = ui.spinPort->value(); m_pTcpClient->connectToHost(addr, port);}void QGuiTcpClient::actDisconnect_triggered(){ if (m_pTcpClient->state() == QAbstractSocket::ConnectedState) m_pTcpClient->disconnectFromHost();}void QGuiTcpClient::actClear_triggered(){ ui.plainTextEdit->clear();}void QGuiTcpClient::btnSend_clicked(){ QString msg = ui.editMsg->text(); ui.plainTextEdit->appendPlainText("[out] " + msg); ui.editMsg->clear(); ui.editMsg->setFocus(); QByteArray str = msg.toUtf8(); str.append('\n'); m_pTcpClient->write(str);}void QGuiTcpClient::closeEvent(QCloseEvent* event){ if (m_pTcpClient->state() == QAbstractSocket::ConnectedState) m_pTcpClient->disconnectFromHost(); event->accept();}QString QGuiTcpClient::getLocalIP(){ QString hostName = QHostInfo::localHostName();//本地主機名 QHostInfo hostInfo = QHostInfo::fromName(hostName); QString localIP = ""; QList addList = hostInfo.addresses();// if (!addList.isEmpty()) { for (int i = 0; i < addList.count(); i++) { QHostAddress aHost = addList.at(i); if (QAbstractSocket::IPv4Protocol == aHost.protocol()) { localIP = aHost.toString(); break; } } } return localIP;}

總結

以上是生活随笔為你收集整理的qt tcp通信_Qt之网络编程TCP通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。