1. 程式人生 > >QT中的SOCKET的通訊

QT中的SOCKET的通訊

1、服務端程式

  1. //ui_widget.h
  2. #ifndef UI_WIDGET_H
  3. #define UI_WIDGET_H
  4. #include <QtCore/QVariant>
  5. #include <QtGui/QAction>
  6. #include <QtGui/QApplication>
  7. #include <QtGui/QButtonGroup>
  8. #include <QtGui/QHeaderView>
  9. #include <QtGui/QPushButton>
  10. #include <QtGui/QTextEdit>
  11. #include <QtGui/QWidget>
  12. QT_BEGIN_NAMESPACE  
  13. class Ui_Widget  
  14. {  
  15. public:  
  16.     QTextEdit *textSend;  
  17.     QPushButton *send;  
  18.     QTextEdit *textReceive;  
  19.     QPushButton *receive;  
  20.     void setupUi(QWidget *Widget)  
  21.     {  
  22.         if (Widget->objectName().isEmpty())  
  23.             Widget->setObjectName(QString::fromUtf8("Widget"
    ));  
  24.         Widget->resize(626, 286);  
  25.         textSend = new QTextEdit(Widget);  
  26.         textSend->setObjectName(QString::fromUtf8("textSend"));  
  27.         textSend->setGeometry(QRect(10, 10, 281, 191));  
  28.         send = new QPushButton(Widget);  
  29.         send->setObjectName(QString::fromUtf8("send"
    ));  
  30.         send->setGeometry(QRect(10, 220, 281, 41));  
  31.         textReceive = new QTextEdit(Widget);  
  32.         textReceive->setObjectName(QString::fromUtf8("textReceive"));  
  33.         textReceive->setGeometry(QRect(320, 10, 281, 191));  
  34.         receive = new QPushButton(Widget);  
  35.         receive->setObjectName(QString::fromUtf8("receive"));  
  36.         receive->setGeometry(QRect(320, 220, 281, 41));  
  37.         retranslateUi(Widget);  
  38.         QMetaObject::connectSlotsByName(Widget);  
  39.     } // setupUi
  40.     void retranslateUi(QWidget *Widget)  
  41.     {  
  42.         Widget->setWindowTitle(QApplication::translate("Widget""Widget", 0, QApplication::UnicodeUTF8));  
  43.         send->setText(QApplication::translate("Widget""/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));  
  44.         receive->setText(QApplication::translate("Widget""/346/216/245/346/224/266", 0, QApplication::UnicodeUTF8));  
  45.         Q_UNUSED(Widget);  
  46.     } // retranslateUi
  47. };  
  48. namespace Ui {  
  49.     class Widget: public Ui_Widget {};  
  50. // namespace Ui
  51. QT_END_NAMESPACE  
  52. #endif // UI_WIDGET_H
  53. //widget.h
  54. #ifndef WIDGET_H
  55. #define WIDGET_H
  56. #include <QtGui/QWidget>
  57. #include <QUdpSocket>
  58. namespace Ui  
  59. {  
  60.     class Widget;  
  61. }  
  62. class Widget : public QWidget  
  63. {  
  64.     Q_OBJECT  
  65. public:  
  66.     Widget(QWidget *parent = 0);  
  67.     ~Widget();  
  68.     int port1;  
  69.     int port2;  
  70.     QHostAddress *hostaddr1;  
  71.     QHostAddress *hostaddr2;  
  72. private:  
  73.     Ui::Widget *ui;  
  74.     QUdpSocket *udpSocket;  
  75. private slots:  
  76.     void send();  
  77.     void receive();  
  78. };  
  79. #endif // WIDGET_H
  80. //widget.cpp
  81. #include "widget.h"
  82. #include "ui_widget.h"
  83. #include <QMessageBox>
  84. Widget::Widget(QWidget *parent)  
  85.     : QWidget(parent), ui(new Ui::Widget)  
  86. {  
  87.     ui->setupUi(this);  
  88.     port1=4444;  
  89.     port2=4445;  
  90.     hostaddr1 = new QHostAddress("10.10.19.162");  
  91.     hostaddr2 = new QHostAddress("10.10.19.161");  
  92.     //建立 QUdpSocket 物件
  93.     udpSocket=new QUdpSocket(this);  
  94.     bool conn=udpSocket->bind(*hostaddr2,port2);  //伺服器端IP為10.10.19.161,埠為4445
  95.     //連結失敗
  96.     if(!conn){  
  97.         QMessageBox box;  
  98.         box.setText(tr("連結錯誤"));  
  99.         box.exec();  
  100.     }else{  
  101.         //把udpSocket的訊號關聯到槽
  102.         connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));  
  103.         connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));  
  104.     }  
  105.     setWindowTitle(tr("伺服器端"));  
  106. }  
  107. Widget::~Widget()  
  108. {  
  109.     delete ui;  
  110. }  
  111. void Widget::send()  
  112. {  
  113.     QMessageBox box;  
  114.     QString text=ui->textSend->toPlainText();  
  115.     if(text.length()==0){  
  116.         box.setText(tr("請輸入傳送內容"));  
  117.     }  
  118.     /*開始傳送資料*/
  119.     //初始化長度
  120.     int len=0;  
  121.     //udpSocket->writeDatagram(傳送的資料,傳送資料的長度,IP,埠); 返回一個長度.
  122.     len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr1,port1);  
  123.     if(len){  
  124.         box.setText(tr("傳送成功"));  
  125.     }  
  126.     box.exec();  
  127. }  
  128. void Widget::receive()  
  129. {  
  130.     while(udpSocket->hasPendingDatagrams()){    //是否讀到資料
  131.         QByteArray data;  
  132.         //udpSocket->pendingDatagramSize 獲取報文長度
  133.         //data.resize 給 data 陣列設定長度
  134.         data.resize(udpSocket->pendingDatagramSize());  
  135.         //讀入資料
  136.         udpSocket->readDatagram(data.data(),data.size());  
  137.         //顯示資料內容
  138.         QString str=data.data();  
  139.         ui->textReceive->insertPlainText(str+"/r/n");  
  140.     }  
  141. }  
  142. //main.cpp
  143. #include <QtGui/QApplication>
  144. #include <QTextCodec>
  145. #include "widget.h"
  146. int main(int argc, char *argv[])  
  147. {  
  148.     QApplication a(argc, argv);  
  149.     QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));  
  150.     Widget w;  
  151.     w.show();  
  152.     return a.exec();  
  153. }  

2、客戶端程式

  1. //ui_widget.h
  2. #ifndef UI_WIDGET_H
  3. #define UI_WIDGET_H
  4. #include <QtCore/QVariant>
  5. #include <QtGui/QAction>
  6. #include <QtGui/QApplication>
  7. #include <QtGui/QButtonGroup>
  8. #include <QtGui/QHeaderView>
  9. #include <QtGui/QPushButton>
  10. #include <QtGui/QTextEdit>
  11. #include <QtGui/QWidget>
  12. QT_BEGIN_NAMESPACE  
  13. class Ui_Widget  
  14. {  
  15. public:  
  16.     QPushButton *close;  
  17.     QTextEdit *textReceive;  
  18.     QPushButton *send;  
  19.     QTextEdit *textSend;  
  20.     void setupUi(QWidget *Widget)  
  21.     {  
  22.         if (Widget->objectName().isEmpty())  
  23.             Widget->setObjectName(QString::fromUtf8("Widget"));  
  24.         Widget->resize(604, 275);  
  25.         close = new QPushButton(Widget);  
  26.         close->setObjectName(QString::fromUtf8("close"));  
  27.         close->setGeometry(QRect(20, 20, 251, 41));  
  28.         textReceive = new QTextEdit(Widget);  
  29.         textReceive->setObjectName(QString::fromUtf8("textReceive"));  
  30.         textReceive->setGeometry(QRect(20, 80, 251, 171));  
  31.         send = new QPushButton(Widget);  
  32.         send->setObjectName(QString::fromUtf8("send"));  
  33.         send->setGeometry(QRect(320, 20, 251, 41));  
  34.         textSend = new QTextEdit(Widget);  
  35.         textSend->setObjectName(QString::fromUtf8("textSend"));  
  36.         textSend->setGeometry(QRect(320, 80, 251, 171));  
  37.         retranslateUi(Widget);  
  38.         QMetaObject::connectSlotsByName(Widget);  
  39.     } // setupUi
  40.     void retranslateUi(QWidget *Widget)  
  41.     {  
  42.         Widget->setWindowTitle(QApplication::translate("Widget""Widget", 0, QApplication::UnicodeUTF8));  
  43.         close->setText(QApplication::translate("Widget""/345/205/263/351/227/255", 0, QApplication::UnicodeUTF8));  
  44.         send->setText(QApplication::translate("Widget""/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));  
  45.         Q_UNUSED(Widget);  
  46.     } // retranslateUi
  47. };  
  48. namespace Ui {  
  49.     class Widget: public Ui_Widget {};  
  50. // namespace Ui
  51. QT_END_NAMESPACE  
  52. #endif // UI_WIDGET_H
  53. //widget.h
  54. #ifndef WIDGET_H
  55. #define WIDGET_H
  56. #include <QtGui/QWidget>
  57. #include <QUdpSocket>
  58. namespace Ui  
  59. {  
  60.     class Widget;  
  61. }  
  62. class Widget : public QWidget  
  63. {  
  64.     Q_OBJECT  
  65. public:  
  66.     Widget(QWidget *parent = 0);  
  67.     ~Widget();  
  68.     int port1;  
  69.     int port2;  
  70.     QHostAddress *hostaddr1;  
  71.     QHostAddress *hostaddr2;  
  72. private:  
  73.     Ui::Widget *ui;  
  74.     QUdpSocket *udpSocket;  
  75. private slots:  
  76.     void send();  
  77.     void receive();  
  78. };  
  79. #endif // WIDGET_H
  80. //widget.cpp
  81. #include "widget.h"
  82. #include "ui_widget.h"
  83. #include <QTextCodec>
  84. #include <QMessageBox>
  85. Widget::Widget(QWidget *parent)  
  86.     : QWidget(parent), ui(new Ui::Widget)  
  87. {  
  88.     ui->setupUi(this);  
  89.     port1=4444;  
  90.     port2=4445;  
  91.     hostaddr1 = new QHostAddress("10.10.19.162");  
  92.     hostaddr2 = new QHostAddress("10.10.19.161");  
  93.     setWindowTitle(tr("接收端"));  
  94.     //例項化QUdpSocket 物件...
  95.     udpSocket=new QUdpSocket(this);  
  96.     //監聽埠
  97.     bool conn=udpSocket->bind(*hostaddr1,port1);  //客戶端的IP為10.10.19.162,埠號為4444。
  98.     //連結失敗
  99.     if(!conn){  
  100.         QMessageBox box;  
  101.         box.setText(tr("連結錯誤"));  
  102.         box.exec();  
  103.     }else{  
  104.         //把udpSocket的訊號關聯到槽
  105.         connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));  
  106.         connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));  
  107.     }  
  108.      connect(ui->close,SIGNAL(clicked()),this,SLOT(close()));  
  109. }  
  110. Widget::~Widget()  
  111. {  
  112.     delete ui;  
  113. }  
  114. void Widget::send()  
  115. {  
  116.     QMessageBox box;  
  117.     QString text=ui->textSend->toPlainText();  
  118.     if(text.length()==0){  
  119.         box.setText(tr("請輸入傳送內容"));  
  120.     }  
  121.     /*開始傳送資料*/
  122.     //初始化長度
  123.     int len=0;  
  124.     //udpSocket->writeDatagram(傳送的資料,傳送資料的長度,IP,埠); 返回一個長度.
  125.     len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr2,port2);    //傳送的字元傳送到IP為10.10.19.161和埠為4445的服務端
  126.     if(len){  
  127.         box.setText(tr("傳送成功"));  
  128.     }  
  129.     box.exec();  
  130. }  
  131. void Widget::receive()  
  132. {  
  133.     while(udpSocket->hasPendingDatagrams()){    //是否讀到資料
  134.         QByteArray data;  
  135.         //udpSocket->pendingDatagramSize 獲取報文長度
  136.         //data.resize 給 data 陣列設定長度
  137.         data.resize(udpSocket->pendingDatagramSize());  
  138.         //讀入資料
  139.         udpSocket->readDatagram(data.data(),data.size());  
  140.         //顯示資料內容
  141.         QString str=data.data();  
  142.         ui->textReceive->insertPlainText(str+"/r/n");  
  143.     }  
  144. }  
  145. //main.cpp
  146. #include <QtGui/QApplication>
  147. #include <QTextCodec>
  148. #include "widget.h"
  149. int main(int argc, char *argv[])  
  150. {  
  151.     QApplication a(argc, argv);  
  152.     QTextCodec::setCodecForTr(QTextCodec::codecForLocale());  
  153.     Widget w;  
  154.     w.show();  
  155.     return a.exec();  
  156. }  

3、執行程式如下。

客戶端傳送receive字元時伺服器接收框中顯示receive。服務端傳送service時,客戶端接收框中顯示service

 4、說明

本程式實際實現的是TCP協議,因為雙方都綁定了自己的IP和埠,只有同時識別IP和埠號才能正確的傳送和接收資料。

不過,也可以更改為UDP協議或直接用廣播的形式。

這個程式只是個簡單的例項,但可以通過這個小的例項,將其嵌入到大型的程式裡面,以實現複雜的SOCKET通訊。

相關推薦

QT Socket客戶端與伺服器異常斷開後重連

在現在的專案開發中,經常要使用TCP/IP協議來進行通訊,但有時候與伺服器端的連結由於網路問題導致連線異常或斷開,這就需要我們的軟體能自動重連,在Linux中,我們的思維一般是通過心跳包來監控連線是否斷開,有時候還單獨開一個執行緒,但是在QT中,就變得簡單多了,當連線異常

關於JavaSocket通訊時使用ObjectInputStream與ObjectOutputStream的順序問題

在Java中使用Socket與ServerSocket建立客戶機和伺服器時,若採用ObjectInputStream與ObjectOutputStream建立通訊,則需要注意兩個流的順序。否則會發生兩方互相等待導致死鎖。 下面通過一個例子來證明: 伺服器: package com.gar

AndroidSocket通訊的簡單實現

前言Android Framework 層程式碼中大量使用了 Binder IPC 通訊方式,除此之外,Socket 也是一種重要的 IPC 通訊方式,比如StorageManagerService(8.0 之前叫 MountService)與 Vold 之前的通訊,Syst

C#Socket通訊程式設計的非同步實現

本文將在C#中Socket同步通訊的基礎上,分析和研究Socket非同步程式設計的實現方法,目的是深入瞭解Socket程式設計的基本原理,增強對網路遊戲開發相關內容的認識。 什麼是Socket程式設計的非同步是實現 所謂Socket程式設計的非同步實現是指按

QT TCP socket通訊(一)

TCP即Transmission Control Protocol,傳輸控制協議。與UDP不同,它是面向連線和資料流的可靠傳輸協議。也就是說,它能使一臺計算機上的資料無差錯的發往網路上的其他計算機,所以當要傳輸大量資料時,我們選用TCP協議。 TCP協議的程式使用的是客

詳解C#Socket通訊(四):使用雜湊表管理客戶端

public void StartListening() { //獲取本機IP地址 IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); HostIP = ipHo

QTSOCKET通訊

1、服務端程式//ui_widget.h#ifndef UI_WIDGET_H#define UI_WIDGET_H#include <QtCore/QVariant>#include <QtGui/QAction>#include &l

Qt採用多執行緒實現Socket程式設計

      本文介紹的是Qt中採用多執行緒Socket程式設計,由於工作專案的需要,使用Qt的socket程式設計。Qt裡的example是個不錯的教程,但是當我把程式碼移植

QtQchart外掛實現PMW3901迷你光流模組上位機(串列埠通訊

文章目錄 Qt中Qchart外掛實現PMW3901迷你光流模組上位機 光流計介紹 上位機 完整工程[猛戳這兒](https://github.com/LiangtaoZhong/PMW3901-monitor)。

JAVASocket服務端和客戶端網路通訊簡單案例

一. 簡單介紹下Socket的用途: 1.Java最初是作為網路程式語言出現的,其對網路提供了高度的支援,使得客戶端和伺服器的溝通變成了現實,而在網路程式設計中,使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相關的技術 2.IP地址+埠號組成了所

Android Socket通訊

       公司新專案中涉及到Socket通訊有關的東西,雖然之前接觸到一點,不過好長時間不用基本上忘個七七八八了,網上查了查資料,根據專案中的需求自己做了個小Demo,歡迎大家指正. 1.需求:       1.1:客戶端測量完畢後,將測量資料以Socket的方式上傳

Socket通訊粘包分包問題的介紹和解決(C#)

最近在做Unity區域網時,用到了Socket通訊基於TCP協議,然後使用非同步方式,主要用到了BeginAccept和BeginReceive方法 然而就可以實現非同步通訊,然而還是要解決粘包和分包問題 這裡我先說明一下什麼是分包和粘包,TCP提供面向連線的、可靠的資料流傳輸,所以當我們傳

(websocket)協議Ping Pong,Socket通訊ping pong(長連線)

- websocket協議,長連線;Http短連線 WebSocket如何建立連線、交換資料的細節,以及資料幀的格式。  WebSocket複用了HTTP的握手通道。具體指的是,客戶端通過HTTP請求與WebSocket服務端協商升級協議。協議升級完成後,後續的資料交換則遵照WebSock

Socket 通訊由 read 返回值造成的的死鎖問題(socket 阻塞)

詳細見原文。 示例 在第一章中,作者給出了一個 TCP Socket 通訊的例子——反饋伺服器,即伺服器端直接把從客戶端接收到的資料原原本本地反饋回去。 問題的引出 明確問題 客戶端與伺服器端在接收和傳送資料時,read()和write()方法不一

Linux系統網路程式設計TCP通訊socket--send導致程序被關閉

send(sockfd, buff, sizeof(buff), 0); 在linuxTCP通訊中上述send形式是常用的設定方式,但是如果在TCP連結斷開後呼叫該send函式,多次即會導致程序結束。 解決方法 最簡單的方式就是 send(sockfd, buff, sizeo

SOCKET通訊TCP、UDP資料包大小的確定

TCP、UDP資料包大小的確定 UDP和TCP協議利用埠號實現多項應用同時傳送和接收資料。資料通過源埠傳送出去,通過目標埠接收。有的網路應用只能使用預留或註冊的靜態埠;而另外一些網路應用則可以使用未被註冊的動態埠。因為UDP和TCP報頭使用兩個位元組存放埠號,所以埠號的有效範圍是從0到6

Socket通訊AF_INET 和 AF_UNIX域的區別

轉載:http://blog.csdn.net/sandware/article/details/40923491 1.  AF_INET域socket通訊過程 典型的TCP/IP四層模型的通訊過程。 傳送方、接收方依賴IP:Port來標識,即將本地的socket繫結到對應的IP埠上,傳送資料時

UnitySocket通訊(多個客戶端的非同步通訊

using UnityEngine; using System; using System.Net; using System.Net.Sockets; using System.Collections; using System.Text; using System.Collections.Generic;

【轉】Unity3d的Tcp socket通訊(開源)

轉自:https://blog.csdn.net/hiramtan/article/details/72621787HiSocket_unity如何使用可以從此連結下載最新的unity package: 功能Tcp socketUdp socket可伸縮位元組表高效能位元組塊

java各種通訊的例項(socket、http等)

socket通訊的例項: 服務端: /**  * <b>專案名:</b>複習總結<br/>  * <b>包   名:</b>socket<br/>  * <b>檔名:</b>Se