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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Qt的Socket通信

發布時間:2024/4/11 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt的Socket通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Qt的Socket通信

文章目錄

    • Qt的Socket通信
    • 1 TCP/IP
    • 2. UDP
    • 3. TCP/IP 和 UDP的區別

Qt中提供的所有的Socket類都是非阻塞的。
Qt中常用的用于socket通信的套接字類:

  • QTcpServer

用于TCP/IP通信, 作為服務器端套接字使用

  • QTcpSocket

用于TCP/IP通信,作為客戶端套接字使用。

  • QUdpSocket

用于UDP通信,服務器,客戶端均使用此套接字。

1 TCP/IP

在Qt中實現TCP/IP服務器端通信的流程:

  • 創建套接字
  • 將套接字設置為監聽模式
  • 等待并接受客戶端請求
    可以通過QTcpServer提供的void newConnection()信號來檢測是否有連接請求,如果有可以在對應的槽函數中調用nextPendingConnection函數獲取到客戶端的Socket信息(返回值為QTcpSocket*類型指針),通過此套接字與客戶端之間進行通信
  • 接收或者向客戶端發送數據
  • 接收數據:使用read()或者readAll()函數
  • 發送數據:使用write()函數

客戶端通信流程:

  • 創建套接字
  • 連接服務器
  • 可以使用QTcpSocket類的connectToHost()函數來連接服務器。
  • 向服務器發送或者接受數據

下面例子為簡單的TCP/IP通信的實現:
服務器端
通過Qt提供的QTcpServer類實現服務器端的socket通信:

//---------- tcpserver.h ------------ class TCPServer : public QMainWindow {Q_OBJECTpublic:explicit TCPServer(QWidget *parent = 0);~TCPServer();public slots:void slotNewConnection();void slotReadyRead();private:Ui::TCPServer *ui;// 負責監聽的套接字QTcpServer* m_server;// 負責通信的套接字QTcpSocket* m_client; };//---------- tcpserver.cpp ------------ TCPServer::TCPServer(QWidget *parent) :QMainWindow(parent),ui(new Ui::TCPServer),m_server(NULL),m_client(NULL) {ui->setupUi(this);//創建套接字對象m_server = new QTcpServer(this);//將套接字設置為監聽模式m_server->listen(QHostAddress::Any, 9999);//通過信號接收客戶端請求,如果收到鏈接請求會有newConnection信號connect(m_server, &QTcpServer::newConnection, this, &TCPServer::slotNewConnection); }TCPServer::~TCPServer() {delete ui; }void TCPServer::slotNewConnection() {if(m_client == NULL){//處理客戶端的連接請求,獲取通信socketm_client = m_server->nextPendingConnection();//發送數據m_client->write("服務器連接成功!!!");//連接信號, 接收客戶端數據,有數據到來會收到readyRead信號connect(m_client, &QTcpSocket::readyRead, this, &TCPServer::slotReadyRead);} }void TCPServer::slotReadyRead() {//接收數據QByteArray array = m_client->readAll();QMessageBox::information(this, "Client Message", array); }

客戶端
客戶端通過使用Qt提供的QTcpSocket類可以方便的實現與服務器端的通信。

//------------- tcpclient.h ------------ class TCPClient : public QMainWindow {Q_OBJECTpublic:explicit TCPClient(QWidget *parent = 0);~TCPClient();public slots:void slotReadyRead();void slotSendMsg();private:Ui::TCPClient *ui;QTcpSocket* m_client;};//------------- tcpclient.cpp -------------- TCPClient::TCPClient(QWidget *parent) :QMainWindow(parent),ui(new Ui::TCPClient) {ui->setupUi(this);//創建套接字m_client = new QTcpSocket(this);//連接服務器m_client->connectToHost(QHostAddress("127.0.0.1"), 9999);//通過信號readyRead接收服務器數據connect(m_client, &QTcpSocket::readyRead, this, &TCPClient::slotReadyRead);//發送按鈕connect(ui->btnSend, &QPushButton::clicked, this, &TCPClient::slotSendMsg); }TCPClient::~TCPClient() {delete ui; }void TCPClient::slotReadyRead() {//接收數據QByteArray array = m_client->readAll();QMessageBox::information(this, "Server Message", array); }void TCPClient::slotSendMsg() {QString text = ui->textEdit->toPlainText();//發送數據m_client->write(text.toUtf8());ui->textEdit->clear(); }

2. UDP

使用Qt提供的QUdpSocket進行UDP通信。在UDP方式下,客戶端并不與服務器建立連接,它只負責調用發送函數向服務器發送數據。類似的服務器也不從客戶端接收連接,只負責調用接收函數,等待來自客戶端的數據的到達。

在UDP通信中,服務器端和客戶端的概念已經顯得有些淡化,兩部分做的工作都大致相同:

  • 創建套接字
  • 綁定套接字
    在UDP中如果需要接收數據則需要對套接字進行綁定,只發送數據則不需要對套接字進行綁定。
  • 通過調用bind()函數將套接字綁定到指定端口上。
  • 接收或者發送數據
  • 接收數據:使用readDatagram()接收數據,函數聲明如下:
qint64 readDatagram(char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0)參數: data: 接收數據的緩存地址 maxSize: 緩存接收的最大字節數 address: 數據發送方的地址(一般使用提供的默認值) port: 數據發送方的端口號(一般使用提供的默認值) 使用pendingDatagramSize()可以獲取到將要接收的數據的大小, 根據該函數返回值來準備對應大小的內存空間存放將要接收的數據。
  • 發送數據: 使用writeDatagram()函數發送數據,函數聲明如下:
qint64 writeDatagram(const QByteArray & datagram, const QHostAddress & host, quint16 port)參數: datagram:要發送的字符串 host:數據接收方的地址 port:數據接收方的端口號 #include "widget.h" #include "ui_widget.h" #include <QHostAddress>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);udpsocket = new QUdpSocket(this);udpsocket->bind(9090);setWindowTitle("server port is 9090");connect(udpsocket,&QUdpSocket::readyRead,[=](){char buf[1024] = {0};QHostAddress clientaddr;quint16 clientport;quint64 size = udpsocket->readDatagram(buf,sizeof(buf),&clientaddr,&clientport);if(size> 0){QString str = QString("[%1 : %2] : %3").arg(clientaddr.toString()).arg(clientport).arg(buf);ui->textEdit->append(str);}}); }Widget::~Widget() {delete ui; }void Widget::on_ButtonSend_clicked() {QString ip = ui->lineEditIP->text();quint16 port = ui->lineEditPort->text().toInt();QString str = ui->textEdit->toPlainText();udpsocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port); }

廣播

  • 在使用QUdpSocket類的writeDatagram()函數發送數據的時候,其中第二個參數host應該指定為廣播地址:QHostAddress::Broadcast此設置相當于QHostAddress(“255.255.255.255”)
  • 使用UDP廣播的的特點:
  • 使用UDP進行廣播,局域網內的其他的UDP用戶全部可以收到廣播的消息
  • UDP廣播只能在局域網范圍內使用

組播

  • 我們再使用廣播發送消息的時候會發送給所有用戶,但是有些用戶是不想接受消息的,這時候我們就應該使用組播,接收方只有先注冊到組播地址中才能收到組播消息,否則則接受不到消息。另外組播是可以在Internet中使用的。

在使用QUdpSocket類的writeDatagram()函數發送數據的時候,其中第二個參數host應該指定為組播地址,關于組播地址的分類:

  • 224.0.0.0~224.0.0.255為預留的組播地址(永久組地址),地址224.0.0.0保留不做分配,其它地址供路由協議使用;
  • 224.0.1.0~224.0.1.255是公用組播地址,可以用于Internet;
  • 224.0.2.0~238.255.255.255為用戶可用的組播地址(臨時組地址),全網范圍內有效;
  • 239.0.0.0~239.255.255.255為本地管理組播地址,僅在特定的本地范圍內有效。
    注冊加入到組播地址需要使用QUdpSocket類的成員函數:
bool joinMulticastGroup(const QHostAddress & groupAddress)

3. TCP/IP 和 UDP的區別

總結

以上是生活随笔為你收集整理的Qt的Socket通信的全部內容,希望文章能夠幫你解決所遇到的問題。

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