转:http://blog.csdn.net/xiaoyangger/article/details/5758779
1、服务端程序
- //ui_widget.h
- #ifndef UI_WIDGET_H
- #define UI_WIDGET_H
- #include <QtCore/QVariant>
- #include <QtGui/QAction>
- #include <QtGui/QApplication>
- #include <QtGui/QButtonGroup>
- #include <QtGui/QHeaderView>
- #include <QtGui/QPushButton>
- #include <QtGui/QTextEdit>
- #include <QtGui/QWidget>
- QT_BEGIN_NAMESPACE
- class Ui_Widget
- {
- public:
- QTextEdit *textSend;
- QPushButton *send;
- QTextEdit *textReceive;
- QPushButton *receive;
- void setupUi(QWidget *Widget)
- {
- if (Widget->objectName().isEmpty())
- Widget->setObjectName(QString::fromUtf8("Widget"));
- Widget->resize(626, 286);
- textSend = new QTextEdit(Widget);
- textSend->setObjectName(QString::fromUtf8("textSend"));
- textSend->setGeometry(QRect(10, 10, 281, 191));
- send = new QPushButton(Widget);
- send->setObjectName(QString::fromUtf8("send"));
- send->setGeometry(QRect(10, 220, 281, 41));
- textReceive = new QTextEdit(Widget);
- textReceive->setObjectName(QString::fromUtf8("textReceive"));
- textReceive->setGeometry(QRect(320, 10, 281, 191));
- receive = new QPushButton(Widget);
- receive->setObjectName(QString::fromUtf8("receive"));
- receive->setGeometry(QRect(320, 220, 281, 41));
- retranslateUi(Widget);
- QMetaObject::connectSlotsByName(Widget);
- } // setupUi
- void retranslateUi(QWidget *Widget)
- {
- Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0, QApplication::UnicodeUTF8));
- send->setText(QApplication::translate("Widget", "/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));
- receive->setText(QApplication::translate("Widget", "/346/216/245/346/224/266", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(Widget);
- } // retranslateUi
- };
- namespace Ui {
- class Widget: public Ui_Widget {};
- } // namespace Ui
- QT_END_NAMESPACE
- #endif // UI_WIDGET_H
- //widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
- #include <QtGui/QWidget>
- #include <QUdpSocket>
- namespace Ui
- {
- class Widget;
- }
- class Widget : public QWidget
- {
- Q_OBJECT
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- int port1;
- int port2;
- QHostAddress *hostaddr1;
- QHostAddress *hostaddr2;
- private:
- Ui::Widget *ui;
- QUdpSocket *udpSocket;
- private slots:
- void send();
- void receive();
- };
- #endif // WIDGET_H
- //widget.cpp
- #include "widget.h"
- #include "ui_widget.h"
- #include <QMessageBox>
- Widget::Widget(QWidget *parent)
- : QWidget(parent), ui(new Ui::Widget)
- {
- ui->setupUi(this);
- port1=4444;
- port2=4445;
- hostaddr1 = new QHostAddress("10.10.19.162");
- hostaddr2 = new QHostAddress("10.10.19.161");
- //创建 QUdpSocket 对象
- udpSocket=new QUdpSocket(this);
- bool conn=udpSocket->bind(*hostaddr2,port2); //服务器端IP为10.10.19.161,端口为4445
- //链接失败
- if(!conn){
- QMessageBox box;
- box.setText(tr("链接错误"));
- box.exec();
- }else{
- //把udpSocket的信号关联到槽
- connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));
- connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));
- }
- setWindowTitle(tr("服务器端"));
- }
- Widget::~Widget()
- {
- delete ui;
- }
- void Widget::send()
- {
- QMessageBox box;
- QString text=ui->textSend->toPlainText();
- if(text.length()==0){
- box.setText(tr("请输入发送内容"));
- }
- /*开始发送数据*/
- //初始化长度
- int len=0;
- //udpSocket->writeDatagram(发送的数据,发送数据的长度,IP,端口); 返回一个长度.
- len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr1,port1);
- if(len){
- box.setText(tr("发送成功"));
- }
- box.exec();
- }
- void Widget::receive()
- {
- while(udpSocket->hasPendingDatagrams()){ //是否读到数据
- QByteArray data;
- //udpSocket->pendingDatagramSize 获取报文长度
- //data.resize 给 data 数组设置长度
- data.resize(udpSocket->pendingDatagramSize());
- //读入数据
- udpSocket->readDatagram(data.data(),data.size());
- //显示数据内容
- QString str=data.data();
- ui->textReceive->insertPlainText(str+"/r/n");
- }
- }
- //main.cpp
- #include <QtGui/QApplication>
- #include <QTextCodec>
- #include "widget.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));
- Widget w;
- w.show();
- return a.exec();
- }
2、客户端程序
- //ui_widget.h
- #ifndef UI_WIDGET_H
- #define UI_WIDGET_H
- #include <QtCore/QVariant>
- #include <QtGui/QAction>
- #include <QtGui/QApplication>
- #include <QtGui/QButtonGroup>
- #include <QtGui/QHeaderView>
- #include <QtGui/QPushButton>
- #include <QtGui/QTextEdit>
- #include <QtGui/QWidget>
- QT_BEGIN_NAMESPACE
- class Ui_Widget
- {
- public:
- QPushButton *close;
- QTextEdit *textReceive;
- QPushButton *send;
- QTextEdit *textSend;
- void setupUi(QWidget *Widget)
- {
- if (Widget->objectName().isEmpty())
- Widget->setObjectName(QString::fromUtf8("Widget"));
- Widget->resize(604, 275);
- close = new QPushButton(Widget);
- close->setObjectName(QString::fromUtf8("close"));
- close->setGeometry(QRect(20, 20, 251, 41));
- textReceive = new QTextEdit(Widget);
- textReceive->setObjectName(QString::fromUtf8("textReceive"));
- textReceive->setGeometry(QRect(20, 80, 251, 171));
- send = new QPushButton(Widget);
- send->setObjectName(QString::fromUtf8("send"));
- send->setGeometry(QRect(320, 20, 251, 41));
- textSend = new QTextEdit(Widget);
- textSend->setObjectName(QString::fromUtf8("textSend"));
- textSend->setGeometry(QRect(320, 80, 251, 171));
- retranslateUi(Widget);
- QMetaObject::connectSlotsByName(Widget);
- } // setupUi
- void retranslateUi(QWidget *Widget)
- {
- Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0, QApplication::UnicodeUTF8));
- close->setText(QApplication::translate("Widget", "/345/205/263/351/227/255", 0, QApplication::UnicodeUTF8));
- send->setText(QApplication::translate("Widget", "/345/217/221/351/200/201", 0, QApplication::UnicodeUTF8));
- Q_UNUSED(Widget);
- } // retranslateUi
- };
- namespace Ui {
- class Widget: public Ui_Widget {};
- } // namespace Ui
- QT_END_NAMESPACE
- #endif // UI_WIDGET_H
- //widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
- #include <QtGui/QWidget>
- #include <QUdpSocket>
- namespace Ui
- {
- class Widget;
- }
- class Widget : public QWidget
- {
- Q_OBJECT
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- int port1;
- int port2;
- QHostAddress *hostaddr1;
- QHostAddress *hostaddr2;
- private:
- Ui::Widget *ui;
- QUdpSocket *udpSocket;
- private slots:
- void send();
- void receive();
- };
- #endif // WIDGET_H
- //widget.cpp
- #include "widget.h"
- #include "ui_widget.h"
- #include <QTextCodec>
- #include <QMessageBox>
- Widget::Widget(QWidget *parent)
- : QWidget(parent), ui(new Ui::Widget)
- {
- ui->setupUi(this);
- port1=4444;
- port2=4445;
- hostaddr1 = new QHostAddress("10.10.19.162");
- hostaddr2 = new QHostAddress("10.10.19.161");
- setWindowTitle(tr("接收端"));
- //实例化QUdpSocket 对象...
- udpSocket=new QUdpSocket(this);
- //监听端口
- bool conn=udpSocket->bind(*hostaddr1,port1); //客户端的IP为10.10.19.162,端口号为4444。
- //链接失败
- if(!conn){
- QMessageBox box;
- box.setText(tr("链接错误"));
- box.exec();
- }else{
- //把udpSocket的信号关联到槽
- connect(udpSocket,SIGNAL(readyRead()),this,SLOT(receive()));
- connect(ui->send,SIGNAL(clicked()),this,SLOT(send()));
- }
- connect(ui->close,SIGNAL(clicked()),this,SLOT(close()));
- }
- Widget::~Widget()
- {
- delete ui;
- }
- void Widget::send()
- {
- QMessageBox box;
- QString text=ui->textSend->toPlainText();
- if(text.length()==0){
- box.setText(tr("请输入发送内容"));
- }
- /*开始发送数据*/
- //初始化长度
- int len=0;
- //udpSocket->writeDatagram(发送的数据,发送数据的长度,IP,端口); 返回一个长度.
- len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr2,port2); //发送的字符发送到IP为10.10.19.161和端口为4445的服务端
- if(len){
- box.setText(tr("发送成功"));
- }
- box.exec();
- }
- void Widget::receive()
- {
- while(udpSocket->hasPendingDatagrams()){ //是否读到数据
- QByteArray data;
- //udpSocket->pendingDatagramSize 获取报文长度
- //data.resize 给 data 数组设置长度
- data.resize(udpSocket->pendingDatagramSize());
- //读入数据
- udpSocket->readDatagram(data.data(),data.size());
- //显示数据内容
- QString str=data.data();
- ui->textReceive->insertPlainText(str+"/r/n");
- }
- }
- //main.cpp
- #include <QtGui/QApplication>
- #include <QTextCodec>
- #include "widget.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
- Widget w;
- w.show();
- return a.exec();
- }
3、运行程序如下。
客户端发送receive字符时服务器接收框中显示receive。服务端发送service时,客户端接收框中显示service
4、说明
本程序实际实现的是TCP协议,因为双方都绑定了自己的IP和端口,只有同时识别IP和端口号才能正确的发送和接收数据。
不过,也可以更改为UDP协议或直接用广播的形式。
这个程序只是个简单的实例,但可以通过这个小的实例,将其嵌入到大型的程序里面,以实现复杂的SOCKET通信。