QT中的SOCKET的通信

转:http://blog.csdn.net/xiaoyangger/article/details/5758779

1、服务端程序

 

  1. //ui_widget.h   
  2. #ifndef UI_WIDGET_H   
  3. #define UI_WIDGET_H   
  4.   
  5. #include <QtCore/QVariant>   
  6. #include <QtGui/QAction>   
  7. #include <QtGui/QApplication>   
  8. #include <QtGui/QButtonGroup>   
  9. #include <QtGui/QHeaderView>   
  10. #include <QtGui/QPushButton>   
  11. #include <QtGui/QTextEdit>   
  12. #include <QtGui/QWidget>   
  13.   
  14. QT_BEGIN_NAMESPACE  
  15.   
  16. class Ui_Widget  
  17. {  
  18. public:  
  19.     QTextEdit *textSend;  
  20.     QPushButton *send;  
  21.     QTextEdit *textReceive;  
  22.     QPushButton *receive;  
  23.   
  24.     void setupUi(QWidget *Widget)  
  25.     {  
  26.         if (Widget->objectName().isEmpty())  
  27.             Widget->setObjectName(QString::fromUtf8("Widget"));  
  28.         Widget->resize(626, 286);  
  29.         textSend = new QTextEdit(Widget);  
  30.         textSend->setObjectName(QString::fromUtf8("textSend"));  
  31.         textSend->setGeometry(QRect(10, 10, 281, 191));  
  32.         send = new QPushButton(Widget);  
  33.         send->setObjectName(QString::fromUtf8("send"));  
  34.         send->setGeometry(QRect(10, 220, 281, 41));  
  35.         textReceive = new QTextEdit(Widget);  
  36.         textReceive->setObjectName(QString::fromUtf8("textReceive"));  
  37.         textReceive->setGeometry(QRect(320, 10, 281, 191));  
  38.         receive = new QPushButton(Widget);  
  39.         receive->setObjectName(QString::fromUtf8("receive"));  
  40.         receive->setGeometry(QRect(320, 220, 281, 41));  
  41.   
  42.         retranslateUi(Widget);  
  43.   
  44.         QMetaObject::connectSlotsByName(Widget);  
  45.     } // setupUi   
  46.   
  47.     void retranslateUi(QWidget *Widget)  
  48.     {  
  49.         Widget->setWindowTitle(QApplication::translate("Widget""Widget", 0, QApplication::UnicodeUTF8));  
  50.         send->setText(QApplication::translate("Widget""/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));  
  51.         receive->setText(QApplication::translate("Widget""/346/216/245/346/224/266", 0, QApplication::UnicodeUTF8));  
  52.         Q_UNUSED(Widget);  
  53.     } // retranslateUi   
  54.   
  55. };  
  56.   
  57. namespace Ui {  
  58.     class Widget: public Ui_Widget {};  
  59. // namespace Ui   
  60.   
  61. QT_END_NAMESPACE  
  62.   
  63. #endif // UI_WIDGET_H   
  64.   
  65.   
  66. //widget.h   
  67. #ifndef WIDGET_H   
  68. #define WIDGET_H   
  69.   
  70. #include <QtGui/QWidget>   
  71. #include <QUdpSocket>   
  72.   
  73. namespace Ui  
  74. {  
  75.     class Widget;  
  76. }  
  77.   
  78. class Widget : public QWidget  
  79. {  
  80.     Q_OBJECT  
  81.   
  82. public:  
  83.     Widget(QWidget *parent = 0);  
  84.     ~Widget();  
  85.     int port1;  
  86.     int port2;  
  87.     QHostAddress *hostaddr1;  
  88.     QHostAddress *hostaddr2;  
  89.   
  90. private:  
  91.     Ui::Widget *ui;  
  92.     QUdpSocket *udpSocket;  
  93.   
  94. private slots:  
  95.     void send();  
  96.     void receive();  
  97. };  
  98.   
  99. #endif // WIDGET_H   
  100.   
  101.   
  102. //widget.cpp   
  103. #include "widget.h"   
  104. #include "ui_widget.h"   
  105. #include <QMessageBox>   
  106.   
  107. Widget::Widget(QWidget *parent)  
  108.     : QWidget(parent), ui(new Ui::Widget)  
  109. {  
  110.     ui->setupUi(this);  
  111.     port1=4444;  
  112.     port2=4445;  
  113.     hostaddr1 = new QHostAddress("10.10.19.162");  
  114.     hostaddr2 = new QHostAddress("10.10.19.161");  
  115.     //创建 QUdpSocket 对象   
  116.     udpSocket=new QUdpSocket(this);  
  117.     bool conn=udpSocket->bind(*hostaddr2,port2);  //服务器端IP为10.10.19.161,端口为4445   
  118.     //链接失败   
  119.     if(!conn){  
  120.         QMessageBox box;  
  121.         box.setText(tr("链接错误"));  
  122.         box.exec();  
  123.     }else{  
  124.         //把udpSocket的信号关联到槽   
  125.         connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));  
  126.         connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));  
  127.     }  
  128.     setWindowTitle(tr("服务器端"));  
  129. }  
  130.   
  131. Widget::~Widget()  
  132. {  
  133.     delete ui;  
  134. }  
  135.   
  136. void Widget::send()  
  137. {  
  138.     QMessageBox box;  
  139.     QString text=ui->textSend->toPlainText();  
  140.     if(text.length()==0){  
  141.         box.setText(tr("请输入发送内容"));  
  142.     }  
  143.     /*开始发送数据*/  
  144.     //初始化长度   
  145.     int len=0;  
  146.     //udpSocket->writeDatagram(发送的数据,发送数据的长度,IP,端口); 返回一个长度.   
  147.     len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr1,port1);  
  148.     if(len){  
  149.         box.setText(tr("发送成功"));  
  150.     }  
  151.     box.exec();  
  152. }  
  153.   
  154. void Widget::receive()  
  155. {  
  156.     while(udpSocket->hasPendingDatagrams()){    //是否读到数据   
  157.         QByteArray data;  
  158.         //udpSocket->pendingDatagramSize 获取报文长度   
  159.         //data.resize 给 data 数组设置长度   
  160.         data.resize(udpSocket->pendingDatagramSize());  
  161.         //读入数据   
  162.         udpSocket->readDatagram(data.data(),data.size());  
  163.         //显示数据内容   
  164.         QString str=data.data();  
  165.         ui->textReceive->insertPlainText(str+"/r/n");  
  166.     }  
  167. }  
  168.   
  169.   
  170. //main.cpp   
  171. #include <QtGui/QApplication>   
  172. #include <QTextCodec>   
  173. #include "widget.h"   
  174.   
  175. int main(int argc, char *argv[])  
  176. {  
  177.     QApplication a(argc, argv);  
  178.     QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));  
  179.     Widget w;  
  180.     w.show();  
  181.     return a.exec();  
  182. }  

 

2、客户端程序

 

  1. //ui_widget.h   
  2. #ifndef UI_WIDGET_H   
  3. #define UI_WIDGET_H   
  4.   
  5. #include <QtCore/QVariant>   
  6. #include <QtGui/QAction>   
  7. #include <QtGui/QApplication>   
  8. #include <QtGui/QButtonGroup>   
  9. #include <QtGui/QHeaderView>   
  10. #include <QtGui/QPushButton>   
  11. #include <QtGui/QTextEdit>   
  12. #include <QtGui/QWidget>   
  13.   
  14. QT_BEGIN_NAMESPACE  
  15.   
  16. class Ui_Widget  
  17. {  
  18. public:  
  19.     QPushButton *close;  
  20.     QTextEdit *textReceive;  
  21.     QPushButton *send;  
  22.     QTextEdit *textSend;  
  23.   
  24.     void setupUi(QWidget *Widget)  
  25.     {  
  26.         if (Widget->objectName().isEmpty())  
  27.             Widget->setObjectName(QString::fromUtf8("Widget"));  
  28.         Widget->resize(604, 275);  
  29.         close = new QPushButton(Widget);  
  30.         close->setObjectName(QString::fromUtf8("close"));  
  31.         close->setGeometry(QRect(20, 20, 251, 41));  
  32.         textReceive = new QTextEdit(Widget);  
  33.         textReceive->setObjectName(QString::fromUtf8("textReceive"));  
  34.         textReceive->setGeometry(QRect(20, 80, 251, 171));  
  35.         send = new QPushButton(Widget);  
  36.         send->setObjectName(QString::fromUtf8("send"));  
  37.         send->setGeometry(QRect(320, 20, 251, 41));  
  38.         textSend = new QTextEdit(Widget);  
  39.         textSend->setObjectName(QString::fromUtf8("textSend"));  
  40.         textSend->setGeometry(QRect(320, 80, 251, 171));  
  41.   
  42.         retranslateUi(Widget);  
  43.   
  44.         QMetaObject::connectSlotsByName(Widget);  
  45.     } // setupUi   
  46.   
  47.     void retranslateUi(QWidget *Widget)  
  48.     {  
  49.         Widget->setWindowTitle(QApplication::translate("Widget""Widget", 0, QApplication::UnicodeUTF8));  
  50.         close->setText(QApplication::translate("Widget""/345/205/263/351/227/255", 0, QApplication::UnicodeUTF8));  
  51.         send->setText(QApplication::translate("Widget""/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));  
  52.         Q_UNUSED(Widget);  
  53.     } // retranslateUi   
  54.   
  55. };  
  56.   
  57. namespace Ui {  
  58.     class Widget: public Ui_Widget {};  
  59. // namespace Ui   
  60.   
  61. QT_END_NAMESPACE  
  62.   
  63. #endif // UI_WIDGET_H   
  64.   
  65.   
  66. //widget.h   
  67. #ifndef WIDGET_H   
  68. #define WIDGET_H   
  69.   
  70. #include <QtGui/QWidget>   
  71. #include <QUdpSocket>   
  72.   
  73. namespace Ui  
  74. {  
  75.     class Widget;  
  76. }  
  77.   
  78. class Widget : public QWidget  
  79. {  
  80.     Q_OBJECT  
  81.   
  82. public:  
  83.     Widget(QWidget *parent = 0);  
  84.     ~Widget();  
  85.     int port1;  
  86.     int port2;  
  87.     QHostAddress *hostaddr1;  
  88.     QHostAddress *hostaddr2;  
  89.   
  90. private:  
  91.     Ui::Widget *ui;  
  92.     QUdpSocket *udpSocket;  
  93.   
  94. private slots:  
  95.     void send();  
  96.     void receive();  
  97. };  
  98.   
  99. #endif // WIDGET_H   
  100.   
  101.   
  102. //widget.cpp   
  103. #include "widget.h"   
  104. #include "ui_widget.h"   
  105. #include <QTextCodec>   
  106. #include <QMessageBox>   
  107.   
  108. Widget::Widget(QWidget *parent)  
  109.     : QWidget(parent), ui(new Ui::Widget)  
  110. {  
  111.     ui->setupUi(this);  
  112.     port1=4444;  
  113.     port2=4445;  
  114.     hostaddr1 = new QHostAddress("10.10.19.162");  
  115.     hostaddr2 = new QHostAddress("10.10.19.161");  
  116.     setWindowTitle(tr("接收端"));  
  117.     //实例化QUdpSocket 对象...   
  118.     udpSocket=new QUdpSocket(this);  
  119.     //监听端口   
  120.     bool conn=udpSocket->bind(*hostaddr1,port1);  //客户端的IP为10.10.19.162,端口号为4444。   
  121.     //链接失败   
  122.     if(!conn){  
  123.         QMessageBox box;  
  124.         box.setText(tr("链接错误"));  
  125.         box.exec();  
  126.     }else{  
  127.         //把udpSocket的信号关联到槽   
  128.         connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));  
  129.         connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));  
  130.     }  
  131.      connect(ui->close,SIGNAL(clicked()),this,SLOT(close()));  
  132. }  
  133.   
  134. Widget::~Widget()  
  135. {  
  136.     delete ui;  
  137. }  
  138.   
  139. void Widget::send()  
  140. {  
  141.     QMessageBox box;  
  142.     QString text=ui->textSend->toPlainText();  
  143.     if(text.length()==0){  
  144.         box.setText(tr("请输入发送内容"));  
  145.     }  
  146.     /*开始发送数据*/  
  147.     //初始化长度   
  148.     int len=0;  
  149.     //udpSocket->writeDatagram(发送的数据,发送数据的长度,IP,端口); 返回一个长度.   
  150.     len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr2,port2);    //发送的字符发送到IP为10.10.19.161和端口为4445的服务端   
  151.     if(len){  
  152.         box.setText(tr("发送成功"));  
  153.     }  
  154.     box.exec();  
  155. }  
  156.   
  157. void Widget::receive()  
  158. {  
  159.     while(udpSocket->hasPendingDatagrams()){    //是否读到数据   
  160.         QByteArray data;  
  161.         //udpSocket->pendingDatagramSize 获取报文长度   
  162.         //data.resize 给 data 数组设置长度   
  163.         data.resize(udpSocket->pendingDatagramSize());  
  164.         //读入数据   
  165.         udpSocket->readDatagram(data.data(),data.size());  
  166.         //显示数据内容   
  167.         QString str=data.data();  
  168.         ui->textReceive->insertPlainText(str+"/r/n");  
  169.     }  
  170. }  
  171.   
  172.   
  173. //main.cpp   
  174. #include <QtGui/QApplication>   
  175. #include <QTextCodec>   
  176. #include "widget.h"   
  177.   
  178. int main(int argc, char *argv[])  
  179. {  
  180.     QApplication a(argc, argv);  
  181.     QTextCodec::setCodecForTr(QTextCodec::codecForLocale());  
  182.     Widget w;  
  183.     w.show();  
  184.     return a.exec();  
  185. }  

 

 

3、运行程序如下。

客户端发送receive字符时服务器接收框中显示receive。服务端发送service时,客户端接收框中显示service

 

 

 

 

 

 4、说明

本程序实际实现的是TCP协议,因为双方都绑定了自己的IP和端口,只有同时识别IP和端口号才能正确的发送和接收数据。

不过,也可以更改为UDP协议或直接用广播的形式。

这个程序只是个简单的实例,但可以通过这个小的实例,将其嵌入到大型的程序里面,以实现复杂的SOCKET通信。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值