zoukankan      html  css  js  c++  java
  • 37.Qt网络与通信

    1  获取本机网络与通信

      在网络应用中,经常需要获得本机的主机名.IP地址和硬件地址等网络信息.运用QHostInfo,QNetWorkInterface,QNetworkAddressEntry可获得本机的网络信息.

    • widget.h
       1 #ifndef WIDGET_H
       2 #define WIDGET_H
       3 
       4 #include <QWidget>
       5 #include <QLabel>
       6 #include <QPushButton>
       7 #include <QLineEdit>
       8 #include <QGridLayout>
       9 #include <QMessageBox>
      10 
      11 #include <QHostInfo>
      12 #include <QNetworkInterface>
      13 
      14 
      15 namespace Ui {
      16 class Widget;
      17 }
      18 
      19 class Widget : public QWidget
      20 {
      21     Q_OBJECT
      22 
      23 public:
      24     explicit Widget(QWidget *parent = 0);
      25     ~Widget();
      26 
      27  private:
      28     QLabel *hostLabel;
      29     QLineEdit *LineEditLocalHostName;
      30     QLabel *ipLabel;
      31     QLineEdit *LineEditAddress;
      32 
      33     QPushButton *detailBtn;
      34 
      35     QGridLayout *mainLayout;
      36 
      37 private:
      38     Ui::Widget *ui;
      39 
      40 public:
      41     void getHostInformation();
      42 
      43 public slots:
      44     void slotDetail();
      45 };
      46 
      47 #endif // WIDGET_H
    • widget.cpp
       1 #include "widget.h"
       2 #include "ui_widget.h"
       3 
       4 Widget::Widget(QWidget *parent) :
       5     QWidget(parent),
       6     ui(new Ui::Widget)
       7 {
       8     ui->setupUi(this);
       9     hostLabel = new QLabel(tr("主机名: "));
      10     LineEditLocalHostName = new QLineEdit;
      11     ipLabel = new QLabel(tr("IP 地址:"));
      12     LineEditAddress = new QLineEdit;
      13 
      14     detailBtn = new QPushButton(tr("详细"));
      15 
      16     mainLayout = new QGridLayout(this);
      17     mainLayout->addWidget(hostLabel,0,0);
      18     mainLayout->addWidget(LineEditLocalHostName,0,1);
      19     mainLayout->addWidget(ipLabel,1,0);
      20     mainLayout->addWidget(LineEditAddress,1,1);
      21     //第二行第0个,占两列
      22     mainLayout->addWidget(detailBtn,2,0,1,2);
      23 
      24     getHostInformation();
      25     connect(detailBtn,SIGNAL(clicked(bool)),this,SLOT(slotDetail()));
      26 }
      27 
      28 Widget::~Widget()
      29 {
      30     delete ui;
      31 }
      32 
      33 void Widget::getHostInformation()
      34 {
      35     //获得本机主机名.QHostInfo提供了一系列有关网络信息的静态函数,
      36     //可以根据主机名获得分配的IP地址,也可以根据IP地址获得相应的主机名
      37     QString localHostName = QHostInfo::localHostName();
      38     LineEditLocalHostName->setText(localHostName);
      39 
      40     //根据主机名获得相关主机信息,包括IP地址等.
      41     //QHostInfo::fromName()函数通过主机名查找IP地址信息
      42     QHostInfo hostInfo = QHostInfo::fromName(localHostName);
      43 
      44     //获得主机的IP地址列表
      45     QList<QHostAddress> listAddress = hostInfo.addresses();
      46 
      47     //在不为空的情况下,使用第一个IP地址
      48     if(!listAddress.isEmpty())
      49     {
      50         LineEditAddress->setText(listAddress.first().toString());
      51     }
      52 }
      53 
      54 void Widget::slotDetail()
      55 {
      56     QString detail="";
      57     //QNetworkInterface类提供了一个IP地址和网络接口的列表
      58     QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
      59 
      60     for(int i=0;i<list.count();i++)
      61     {
      62         QNetworkInterface interface=list.at(i);
      63 
      64         //获得网络接口的名称
      65         detail=detail+tr("设备: ")+interface.name()+"
      ";
      66         //获得网络接口的名称
      67         detail=detail+tr("硬件地址:")+interface.hardwareAddress()+"
      ";
      68 
      69         //每个网络接口包括0个或多个IP地址,
      70         //每个IP地址有选择性地与一个子网掩码和一个广播地址相关联
      71         //QNetworkAddressEntry类存储了被网络接口支持的一个IP地址,
      72         //同时还包括与之相关的子网掩码和广播地址
      73         QList<QNetworkAddressEntry> entryList=interface.addressEntries();
      74 
      75 
      76         for(int j=0;j<entryList.count();j++)
      77         {
      78             QNetworkAddressEntry entry = entryList.at(j);
      79             detail=detail+"	"+tr("IP地址: ")+entry.ip().toString()+"
      ";
      80             detail=detail+"	"+tr("子网掩码: ")+entry.netmask().toString()+"
      ";
      81             detail=detail+"	"+tr("广播地址: ")+entry.broadcast().toString()+"
      ";
      82         }
      83         QMessageBox::information(this,tr("Detail"),detail);
      84     }
      85 }
    • main.cpp
       1 #include "widget.h"
       2 #include <QApplication>
       3 
       4 int main(int argc, char *argv[])
       5 {
       6     QApplication a(argc, argv);
       7     Widget w;
       8     w.show();
       9 
      10     return a.exec();
      11 }

    2  基于UDP的网络广播程序

      2.1  UDP(user data protocol)是一种简单轻量级,不可靠,面向数据报无连接的传输协议,可以用在不是十分重要的场合

      2.2  UDP编程模型

      在UDP方式下客户端并不与服务器建立连接,它只负责调用发送函数向服务器法术数据报.类似的服务器不从客户端接收连接,只负责调用接收函数,等待来自某客户端的数据到达.Qt中通过QUdpSocket类实现UDP协议的编程.

     服务器端:

    • udpserver.h
     1 #ifndef UDPSERVER_H
     2 #define UDPSERVER_H
     3 
     4 #include <QDialog>
     5 #include <QLabel>
     6 #include <QPushButton>
     7 #include <QVBoxLayout>
     8 #include <QLineEdit>
     9 #include <QUdpSocket>
    10 #include <QTimer>
    11 
    12 namespace Ui {
    13 class UdpServer;
    14 }
    15 
    16 class UdpServer : public QDialog
    17 {
    18     Q_OBJECT
    19 
    20 public:
    21     explicit UdpServer(QWidget *parent = 0,Qt::WindowFlags f=0);
    22     ~UdpServer();
    23 
    24 public slots:
    25     void StartBtnClicked();
    26     void timeout();
    27 
    28 private:
    29     int port;
    30     bool isStarted;
    31     QUdpSocket *udpSocket;
    32     QTimer *timer;
    33 
    34 private:
    35     QLabel *TimerLabel;
    36     QLineEdit *TextLineEdit;
    37     QPushButton *StartBtn;
    38     QVBoxLayout *mainLayout;
    39 
    40 private:
    41     Ui::UdpServer *ui;
    42 
    43 
    44 };
    45 
    46 #endif // UDPSERVER_H
    • udpserver.cpp
       1 #include "udpserver.h"
       2 #include "ui_udpserver.h"
       3 
       4 #include <QHostAddress>
       5 
       6 UdpServer::UdpServer(QWidget *parent,Qt::WindowFlags f) :
       7     QDialog(parent,f),
       8     ui(new Ui::UdpServer)
       9 {
      10     ui->setupUi(this);
      11 
      12     setWindowTitle(tr("UDP 服务器"));
      13 
      14     TimerLabel = new QLabel(tr("计时器:"),this);
      15     TextLineEdit = new QLineEdit(this);
      16     StartBtn = new QPushButton(tr("开始"),this);
      17 
      18     //设置垂直布局
      19     mainLayout = new QVBoxLayout(this);
      20     mainLayout->addWidget(TimerLabel);
      21     mainLayout->addWidget(TextLineEdit);
      22     mainLayout->addWidget(StartBtn);
      23 
      24     connect(StartBtn,SIGNAL(clicked(bool)),this,SLOT(StartBtnClicked()));
      25 
      26     //设置UDP的端口号参数,服务器定时向此端口发送广播消息
      27     port = 5555;
      28     isStarted = false;
      29     udpSocket = new QUdpSocket(this);
      30     //创建定时器
      31     timer = new QTimer(this);
      32     //定时发送广播消息
      33     connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
      34 }
      35 
      36 UdpServer::~UdpServer()
      37 {
      38     delete ui;
      39 }
      40 
      41 void UdpServer::StartBtnClicked()
      42 {
      43     //打开
      44     if(!isStarted)
      45     {
      46         StartBtn->setText(tr("停止"));
      47         //每隔1000秒发送一个消息
      48         timer->start(1000);
      49         isStarted=true;
      50     }
      51     else
      52     {
      53         StartBtn->setText(tr("开始"));
      54         isStarted = false;
      55         timer->stop();
      56     }
      57 }
      58 
      59 void UdpServer::timeout()
      60 {
      61     QString msg = TextLineEdit->text();
      62     int length=0;
      63     if(msg=="")
      64     {
      65         return;
      66     }
      67 
      68     //QHostAddress::Broadcast 指定向广播地址发送
      69     if(length=udpSocket->writeDatagram(msg.toLatin1(),
      70                msg.length(),QHostAddress::Broadcast,port)!=msg.length())
      71     {
      72         return;
      73     }
      74 }
    • udpclient.h
       1 #ifndef UDPCLIENT_H
       2 #define UDPCLIENT_H
       3 
       4 #include <QDialog>
       5 #include <QVBoxLayout>
       6 #include <QTextEdit>
       7 #include <QPushButton>
       8 #include <QUdpSocket>
       9 
      10 namespace Ui {
      11 class UdpClient;
      12 }
      13 
      14 class UdpClient : public QDialog
      15 {
      16     Q_OBJECT
      17 
      18 public:
      19     explicit UdpClient(QWidget *parent = 0);
      20     ~UdpClient();
      21 
      22 public slots:
      23     void CloseBtnClicked();
      24     void dataReceived();
      25 
      26 private:
      27     int port;
      28     QUdpSocket *udpSocket;
      29 
      30 private:
      31     Ui::UdpClient *ui;
      32     QTextEdit *ReceiveTextEdit;
      33     QPushButton *closeBtn;
      34     QVBoxLayout *mainLayout;
      35 };
      36 
      37 #endif // UDPCLIENT_H
    • udpclient.cpp
       1 #include "udpclient.h"
       2 #include "ui_udpclient.h"
       3 #include <QMessageBox>
       4 #include <QHostAddress>
       5 
       6 UdpClient::UdpClient(QWidget *parent) :
       7     QDialog(parent),
       8     ui(new Ui::UdpClient)
       9 {
      10     ui->setupUi(this);
      11 
      12     setWindowTitle(tr("UDP 客户端"));
      13 
      14     ReceiveTextEdit = new QTextEdit(this);
      15 
      16     closeBtn = new QPushButton(tr("关闭"),this);
      17 
      18     mainLayout = new QVBoxLayout(this);
      19     mainLayout->addWidget(ReceiveTextEdit);
      20     mainLayout->addWidget(closeBtn);
      21 
      22     connect(closeBtn,SIGNAL(clicked(bool)),this,SLOT(CloseBtnClicked()));
      23 
      24     //设置UDP的端口号参数,指定在此端口上监听数据
      25     port = 5555;
      26 
      27     //创建一个QUdpSocket
      28     udpSocket = new QUdpSocket(this);
      29     //连接QIODevice的readyRead()信号
      30     //QUdpSocket也是一个I/O设备,从QIODevice继承而来,当有数据到达I/O设备时,发出readyRead()信号
      31     connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
      32 
      33     //绑定到指定的端口上
      34     bool result=udpSocket->bind(port);
      35 
      36     if(!result)
      37     {
      38         QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
      39         return;
      40     }
      41 }
      42 
      43 UdpClient::~UdpClient()
      44 {
      45     delete ui;
      46 }
      47 
      48 void UdpClient::CloseBtnClicked()
      49 {
      50     close();
      51 }
      52 
      53 void UdpClient::dataReceived()
      54 {
      55     //判断UdpSocket中是否有数据报可读
      56     //hasPendingDatagrams()方法在至少有一个数据报可读时返回true
      57     while(udpSocket->hasPendingDatagrams())
      58     {
      59         //实现读取第一个数据报
      60         //pendingDataSize()可以获得第一个数据报的长度
      61         QByteArray datagram;
      62         datagram.resize(udpSocket->pendingDatagramSize());
      63         udpSocket->readDatagram(datagram.data(),datagram.size());
      64 
      65         QString msg = datagram.data();
      66         //显示数据内容
      67         ReceiveTextEdit->insertPlainText(msg);
      68     }
      69 }

    3  基于TCP的网络聊天室程序 

      TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地送达网络上的其他计算机.因此,对可靠性要求高的数据通信系统往往使用TCP协议传输数据,但在正则收发数据前通信双方必须首先建立连接.

      首先启动服务器,一段时间后启动客户端,它与此服务器经过三次握手后建立连接.此后的一段时间内,客户端向服务器发送一个请求,服务器处理这个请求,并为客户端发回一个响应.这个过程一直持续下去,知道客户端为服务器发一个文件结束符,并关闭客户端连接,接着服务器也关闭服务器的连接,结束运行或等待一个新的客户端连接.

      Qt中通过QTcpSocket类实现TCP协议的编程.

    代码示例:

    服务器端

    • tcpserver.h
       1 #ifndef TCPSERVER_H
       2 #define TCPSERVER_H
       3 
       4 #include <QDialog>
       5 #include <QListWidget>
       6 #include <QLabel>
       7 #include <QLineEdit>
       8 #include <QPushButton>
       9 #include <QGridLayout>
      10 #include "serverh.h"
      11 
      12 namespace Ui {
      13 class TcpServer;
      14 }
      15 
      16 class TcpServer : public QDialog
      17 {
      18     Q_OBJECT
      19 
      20 public:
      21     explicit TcpServer(QWidget *parent = 0);
      22     ~TcpServer();
      23 
      24 private:
      25     Ui::TcpServer *ui;
      26     QListWidget *ContentListWidget;
      27     QLabel *PortLabe;
      28     QLineEdit *PortLineEdit;
      29     QPushButton *CreateBtn;
      30     QGridLayout *mainLayout;
      31 
      32 private:
      33     int port;
      34     serverh *server;
      35 
      36 public slots:
      37     void slotCreateServer();
      38     void updateServer(QString,int);
      39 
      40 };
      41 
      42 #endif // TCPSERVER_H
    • tcpserver.cpp
       1 #include "tcpserver.h"
       2 #include "ui_tcpserver.h"
       3 
       4 TcpServer::TcpServer(QWidget *parent) :
       5     QDialog(parent),
       6     ui(new Ui::TcpServer)
       7 {
       8     ui->setupUi(this);
       9 
      10     setWindowTitle(tr("TCP Server"));
      11 
      12     ContentListWidget = new QListWidget;
      13 
      14     PortLabe = new QLabel(tr("端口: "));
      15     PortLineEdit = new QLineEdit();
      16 
      17     CreateBtn = new QPushButton(tr("创建聊天室"));
      18 
      19     mainLayout=new QGridLayout(this);
      20     mainLayout->addWidget(ContentListWidget,0,0,1,2);
      21     mainLayout->addWidget(PortLabe,1,0);
      22     mainLayout->addWidget(PortLineEdit,1,1);
      23     mainLayout->addWidget(CreateBtn,2,0,1,2);
      24 
      25     port=8010;
      26     PortLineEdit->setText(QString::number(port));
      27 
      28     connect(CreateBtn,SIGNAL(clicked(bool)),this,SLOT(slotCreateServer()));
      29 }
      30 
      31 TcpServer::~TcpServer()
      32 {
      33     delete ui;
      34 }
      35 
      36 void TcpServer::slotCreateServer()
      37 {
      38     //创建一个serverh对象
      39     server = new serverh(this,port);
      40     //将serverh对象的updateServer()信号与相应的槽函数进行连接
      41     connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
      42 
      43     CreateBtn->setEnabled(false);
      44 }
      45 
      46 void TcpServer::updateServer(QString msg , int length)
      47 {
      48     ContentListWidget->addItem(msg.left(length));
      49 }
    • server.h
       1 #ifndef SERVERH_H
       2 #define SERVERH_H
       3 
       4 #include <QTcpServer>
       5 #include <QObject>
       6 
       7 #include "tcpclientsocket.h"//包含TCP的套接字
       8 
       9 class serverh : public QTcpServer
      10 {
      11     Q_OBJECT
      12 public:
      13     serverh(QObject *parent=0,int port=0);
      14     //用来保存与每一个客户端连接的TcpClientSocket
      15     QList<tcpclientsocket*> tcpClientSocketList;
      16 
      17 signals:
      18     void updateServer(QString,int);
      19 
      20 public slots:
      21     void updateClients(QString,int);
      22     void slotDisconnected(int);
      23 
      24 protected:
      25     void incomingConnection(int socketDescriptor);
      26 };
      27 
      28 #endif // SERVERH_H
    • server.cpp

       1 #include "serverh.h"
       2 
       3 serverh::serverh(QObject *parent,int port):QTcpServer(parent)
       4 {
       5     //在指定的端口对任意地址进行监听
       6     //QHostAddress定义了几种特殊的IP地址
       7     //QHostAddress定义了几种特殊的IP地址,QHostAddress::Null表示一个空的地址
       8     //QHostAddress::LocalHost表示IPV4的本机地址127.0.0.1
       9     //QHostAddress::LocalHostIPV6表示IPv6的本机地址
      10     //QHostAddress::Broadcast表示广播地址255.255.255.255
      11     //QHostAddress::Any表示Ipv4的任意地址0.0.0.0
      12     //QHostAddress::AnyIPv6表示IPv6的任意地址
      13     listen(QHostAddress::Any,port);
      14 }
      15 
      16 //当出现一个新的连接时,QTcpServer触发incomingConnection()函数,参数
      17 //socketDescriptor指定连接的Socket描述符
      18 void serverh::incomingConnection(int socketDescriptor)
      19 {
      20     qDebug() << "receive connect" << endl;
      21     //创建一个新的TcpClientSocket客户端通信
      22     tcpclientsocket  *tcpClientSocket = new tcpclientsocket(this);
      23     //连接TcpClientSocket的updateClients信号
      24     connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,
      25             SLOT(updateClients(QString,int)));
      26     //连接TcpClientSocket的disconnect信号
      27     connect(tcpClientSocket,SIGNAL(disconnected(int)),this,
      28             SLOT(slotDisconnected(int)));
      29 
      30     //将tcpClient加入客户端套接字列表以便管理
      31     tcpClientSocket->setSocketDescriptor(socketDescriptor);
      32 
      33     tcpClientSocketList.append(tcpClientSocket);
      34 }
      35 
      36 void serverh::updateClients(QString msg, int length)
      37 {
      38     //发出updateServer信号,来通知服务器对话框更新相应的显示状态
      39     qDebug() << msg << endl;
      40     emit updateServer(msg,length);
      41     qDebug() << msg << endl;
      42     for(int i=0;i<tcpClientSocketList.count();i++)
      43     {
      44         QTcpSocket *item = tcpClientSocketList.at(i);
      45         if(item->write(msg.toLatin1(),length)!=length)
      46         {
      47             continue;
      48         }
      49     }
      50 }
      51 
      52 void serverh::slotDisconnected(int descriptor)
      53 {
      54     for(int i=0;i<tcpClientSocketList.count();i++)
      55     {
      56         QTcpSocket *item = tcpClientSocketList.at(i);
      57 
      58         if(item->socketDescriptor()==descriptor)
      59         {
      60             tcpClientSocketList.removeAt(i);
      61             return;
      62         }
      63     }
      64     return;
      65 }
    • tcpclientsocket.h
       1 #ifndef TCPCLIENTSOCKET_H
       2 #define TCPCLIENTSOCKET_H
       3 
       4 #include <QTcpSocket>
       5 #include <QObject>
       6 
       7 class tcpclientsocket : public QTcpSocket
       8 {
       9     Q_OBJECT        //添加宏是为了实现信号和槽的通信
      10 public:
      11     tcpclientsocket(QObject *parent=0);
      12 
      13 signals:
      14     void updateClients(QString ,int);
      15     void disconnected(int);
      16 
      17 protected slots:
      18     void dataReceived();
      19     void slotDisconnected();
      20 };
      21 
      22 #endif // TCPCLIENTSOCKET_H
    • tcpclientsocket.cpp
       1 #include "tcpclientsocket.h"
       2 #include <QDebug>
       3 
       4 tcpclientsocket::tcpclientsocket(QObject *parent)
       5 {
       6     //指定信号与槽的连接关系
       7     //readyRead()是QIODevice的signal,由QTcpSocket继承而来.QIODevice
       8     //是所有输入/输出设备的一个抽象类,其中定义了基本的接口,在Qt中,QTcpSocket也被
       9     //看做一个QIODevice,readyRead()信号在有数据到来时发出
      10     connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
      11     //信号在断开连接时发出
      12     connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
      13 }
      14 
      15 //当有数据到来的时候触发dataReceived()函数,从套接字中将有效数据取出,然后
      16 //发出updateClients()信号.
      17 //updateClients()信号是通知服务器向聊天室内的所有成员广播信息
      18 void tcpclientsocket::dataReceived()
      19 {
      20     qDebug() << "accept message" << endl;
      21     while(bytesAvailable()>0)
      22     {
      23         int length = bytesAvailable();
      24         char buf[1024];
      25         read(buf,length);
      26 
      27         qDebug() << buf << endl;
      28         QString msg=buf;
      29         qDebug() << msg << endl;
      30         emit updateClients(msg,length);
      31     }
      32 }
      33 
      34 //槽函数slotDisconnected
      35 void tcpclientsocket::slotDisconnected()
      36 {
      37     emit disconnected(this->socketDescriptor());
      38 }

    客户端

    • tcpclient.h
       1 #ifndef TCPCLIENT_H
       2 #define TCPCLIENT_H
       3 
       4 #include <QDialog>
       5 
       6 namespace Ui {
       7 class TcpClient;
       8 }
       9 
      10 #include <QDialog>
      11 #include <QListWidget>
      12 #include <QLineEdit>
      13 #include <QPushButton>
      14 #include <QLabel>
      15 #include <QGridLayout>
      16 
      17 #include <QHostAddress>
      18 #include <QTcpSocket>
      19 
      20 class TcpClient : public QDialog
      21 {
      22     Q_OBJECT
      23 
      24 public:
      25     explicit TcpClient(QWidget *parent = 0);
      26     ~TcpClient();
      27 
      28 private:
      29     Ui::TcpClient *ui;
      30     QListWidget *contentListWidget;
      31     QLineEdit *sendLineEdit;
      32     QPushButton *sendBtn;
      33     QLabel *userNameLabel;
      34     QLineEdit *userNameLineEdit;
      35     QLabel *serverIPLabel;
      36     QLineEdit *serverIPLineEdit;
      37     QLabel *portLabel;
      38     QLineEdit *portLineEdit;
      39     QPushButton *enterBtn;
      40     QGridLayout *mainLayout;
      41 
      42 private:
      43     bool status;
      44     int port;
      45     QHostAddress *serverIP;
      46     QString userName;
      47     QTcpSocket *tcpSocket;
      48 
      49 private slots:
      50     void slotEnter();
      51     void slotConnected();
      52     void slotDisconnected();
      53     void dataReceived();
      54     void slotSend();
      55 
      56 
      57 };
      58 
      59 #endif // TCPCLIENT_H
    • tcpclient.cpp
        1 #include "tcpclient.h"
        2 #include "ui_tcpclient.h"
        3 
        4 #include <QMessageBox>
        5 #include <QHostInfo>
        6 
        7 TcpClient::TcpClient(QWidget *parent) :
        8     QDialog(parent),
        9     ui(new Ui::TcpClient)
       10 {
       11     ui->setupUi(this);
       12     setWindowTitle(tr("TCP Client"));
       13 
       14     contentListWidget = new QListWidget;
       15 
       16     sendLineEdit = new QLineEdit;
       17     sendBtn = new QPushButton(tr("发送"));
       18 
       19     userNameLabel=new QLabel(tr("用户名:"));
       20     userNameLineEdit = new QLineEdit;
       21 
       22     serverIPLabel = new QLabel(tr("服务器地址: "));
       23     serverIPLineEdit = new QLineEdit;
       24 
       25     portLabel = new QLabel(tr("端口: "));
       26     portLineEdit = new QLineEdit;
       27 
       28     enterBtn = new QPushButton(tr("进入聊天室"));
       29 
       30     mainLayout = new QGridLayout(this);
       31     mainLayout->addWidget(contentListWidget,0,0,1,2);
       32     mainLayout->addWidget(sendLineEdit,1,0);
       33     mainLayout->addWidget(sendBtn,1,1);
       34     mainLayout->addWidget(userNameLabel,2,0);
       35     mainLayout->addWidget(userNameLineEdit,2,1);
       36     mainLayout->addWidget(serverIPLabel,3,0);
       37     mainLayout->addWidget(serverIPLineEdit,3,1);
       38     mainLayout->addWidget(portLabel,4,0);
       39     mainLayout->addWidget(portLineEdit,4,1);
       40     mainLayout->addWidget(enterBtn,5,0,1,2);
       41 
       42     status = false;
       43 
       44     port = 8010;
       45 
       46     portLineEdit->setText(QString::number(port));
       47 
       48     serverIP=new QHostAddress();
       49 
       50     connect(enterBtn,SIGNAL(clicked(bool)),this,SLOT(slotEnter()));
       51     connect(sendBtn,SIGNAL(clicked(bool)),this,SLOT(slotSend()));
       52 
       53     sendBtn->setEnabled(false);
       54 }
       55 
       56 TcpClient::~TcpClient()
       57 {
       58     delete ui;
       59 }
       60 
       61 void TcpClient::slotEnter()
       62 {
       63     //status表示当前的状态,true表示已经进入聊天室,false表示已经离开聊天室
       64     //这里根据status的状态决定是进入还是离开操作
       65     if(!status)
       66     {
       67         //完成输入合法性检验
       68         QString ip = serverIPLineEdit->text();
       69         //用来判断给定的IP地址是否能够被正确解析
       70         if(!serverIP->setAddress(ip))
       71         {
       72             QMessageBox::information(this,tr("error"),tr("server ip address error!"));
       73             return;
       74         }
       75 
       76         if(userNameLineEdit->text()=="")
       77         {
       78             QMessageBox::information(this,tr("error"),tr("User name error!"));
       79             return;
       80         }
       81 
       82         userName = userNameLineEdit->text();
       83 
       84         //创建QTcpSocket类对象,并将信号/槽连接起来
       85         tcpSocket = new QTcpSocket(this);
       86         connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));
       87         connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
       88         connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
       89 
       90         //与TCP服务器端连接,连接成功后发出connected
       91         tcpSocket->connectToHost(*serverIP,port);
       92 
       93         status = true;
       94     }
       95     else
       96     {
       97         int length = 0;
       98         //构建一条离开聊天室的消息
       99         QString msg = userName + tr(":Leave Chat Room");
      100         //通知服务器端以上构造的消息
      101         if( ( length=tcpSocket->write( msg.toLatin1(),msg.length() )  )!=msg.length())
      102         {
      103             return;
      104         }
      105 
      106         //与服务器端口连接,断开后发出disconnected()信号
      107         tcpSocket->disconnectFromHost();
      108 
      109         //将status状态复位
      110         status = false;
      111     }
      112 }
      113 
      114 //当服务器连上成功后,客户端构造一条进入聊天室的消息,并通知服务器
      115 void TcpClient::slotConnected()
      116 {
      117     qDebug() << "进入服务器" << endl;
      118     sendBtn->setEnabled(true);
      119     enterBtn->setText(tr("离开"));
      120 
      121     int length=0;
      122 
      123     QString msg = userName+tr("Enter Chat Room");
      124     if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())
      125     {
      126         qDebug() << "发送失败" << endl;
      127         return;
      128     }
      129     else
      130     {
      131         qDebug() << "发送成功" << endl;
      132     }
      133 }
      134 
      135 void TcpClient::slotDisconnected()
      136 {
      137     sendBtn->setEnabled(false);
      138     enterBtn->setText(tr("进入聊天室"));
      139 }
      140 
      141 //当有数据到来时触发此函数,从套接字中将有效数据提出并显示
      142 void TcpClient::dataReceived()
      143 {
      144     while(tcpSocket->bytesAvailable()>0)
      145     {
      146         QByteArray datagram;
      147         datagram.resize(tcpSocket->bytesAvailable());
      148 
      149         tcpSocket->read(datagram.data(),datagram.size());
      150 
      151         QString msg = datagram.data();
      152         contentListWidget->addItem(msg.left(datagram.size()));
      153     }
      154 }
      155 
      156 void TcpClient::slotSend()
      157 {
      158     if(sendLineEdit->text()=="")
      159     {
      160         return;
      161     }
      162 
      163     QString msg=userName+":"+sendLineEdit->text();
      164 
      165     tcpSocket->write(msg.toLatin1(),msg.length());
      166     sendLineEdit->clear();
      167 }
    • main.cpp
       1 #include "tcpclient.h"
       2 #include <QApplication>
       3 
       4 int main(int argc, char *argv[])
       5 {
       6     QApplication a(argc, argv);
       7     TcpClient w;
       8     w.show();
       9 
      10     return a.exec();
      11 }

    4  网页浏览实例

      首先创建一个QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后关联了管理器的finished信号和自定义的槽,每当网络应答结束时都会发射这个信号.最后使用了get函数来发送一个网络请求,网络请求使用QNetwrokRequest类表示,get()函数返回一个QNetworkReply对象

    • mainwindow.h
       1 #ifndef MAINWINDOW_H
       2 #define MAINWINDOW_H
       3 
       4 #include <QMainWindow>
       5 
       6 #include <QNetworkReply>
       7 #include <QNetworkAccessManager>
       8 class QNetworkAccessManager;
       9 
      10 namespace Ui {
      11 class MainWindow;
      12 }
      13 
      14 class MainWindow : public QMainWindow
      15 {
      16     Q_OBJECT
      17 
      18 public:
      19     explicit MainWindow(QWidget *parent = 0);
      20     ~MainWindow();
      21 
      22 private slots:
      23     void replyFinished(QNetworkReply *);
      24 
      25 
      26 private:
      27     Ui::MainWindow *ui;
      28 
      29     QNetworkAccessManager *manager;
      30 };
      31 
      32 #endif // MAINWINDOW_H
    • mainwindow.cpp
       1 #include "mainwindow.h"
       2 #include "ui_mainwindow.h"
       3 
       4 #include <QtNetwork>
       5 
       6 
       7 MainWindow::MainWindow(QWidget *parent) :
       8     QMainWindow(parent),
       9     ui(new Ui::MainWindow)
      10 {
      11     ui->setupUi(this);
      12 
      13     //创建QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后
      14     //管理了管理器的finished()信号和自定义的槽,每当网络应答结束时都会发射
      15     //这个信号.最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest
      16     //类表示,get()函数返回一个QNetworkReply对象
      17     manager = new QNetworkAccessManager(this);
      18     connect(manager,SIGNAL(finished(QNetworkReply*)),this,
      19             SLOT(replyFinished(QNetworkReply*)));
      20     manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
      21 }
      22 
      23 MainWindow::~MainWindow()
      24 {
      25     delete ui;
      26 }
      27 
      28 void MainWindow::replyFinished(QNetworkReply *reply)
      29 {
      30     QString all = reply->readAll();
      31     ui->textBrowser->setText(all);
      32     reply->deleteLater();
      33 }
    • main.cpp
       1 #include "mainwindow.h"
       2 #include <QApplication>
       3 
       4 int main(int argc, char *argv[])
       5 {
       6     QApplication a(argc, argv);
       7     MainWindow w;
       8     w.show();
       9 
      10     return a.exec();
      11 }

    • 文件下载示例

     mianwindow.h

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 
     6 #include <QNetworkReply>
     7 #include <QNetworkAccessManager>
     8 class QNetworkAccessManager;
     9 
    10 #include <QUrl>
    11 class QFile;
    12 
    13 namespace Ui {
    14 class MainWindow;
    15 }
    16 
    17 class MainWindow : public QMainWindow
    18 {
    19     Q_OBJECT
    20 
    21 public:
    22     explicit MainWindow(QWidget *parent = 0);
    23     ~MainWindow();
    24 
    25     void startRequest(QUrl url);
    26 
    27 private slots:
    28     void replyFinished(QNetworkReply *);
    29     void httpFinished();
    30     void httpReadyRead();
    31     void updateDataReadProgress(qint64,qint64);
    32 
    33 
    34     void on_pushButton_clicked();
    35 
    36 private:
    37     Ui::MainWindow *ui;
    38 
    39     QNetworkAccessManager *manager;
    40 
    41     QNetworkReply *reply;
    42     QUrl url;
    43     QFile *file;
    44 };
    45 
    46 #endif // MAINWINDOW_H

    mainwindow.cpp

      1 #include "mainwindow.h"
      2 #include "ui_mainwindow.h"
      3 
      4 #include <QtNetwork>
      5 
      6 
      7 MainWindow::MainWindow(QWidget *parent) :
      8     QMainWindow(parent),
      9     ui(new Ui::MainWindow)
     10 {
     11     ui->setupUi(this);
     12 
     13     //创建QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后
     14     //管理了管理器的finished()信号和自定义的槽,每当网络应答结束时都会发射
     15     //这个信号.最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest
     16     //类表示,get()函数返回一个QNetworkReply对象
     17     manager = new QNetworkAccessManager(this);
     18     connect(manager,SIGNAL(finished(QNetworkReply*)),this,
     19             SLOT(replyFinished(QNetworkReply*)));
     20 //    manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
     21 
     22     //ui->progressBar->hide();
     23 }
     24 
     25 MainWindow::~MainWindow()
     26 {
     27     delete ui;
     28 }
     29 
     30 void MainWindow::startRequest(QUrl url)
     31 {
     32     //使用get()函数发送网络请求
     33     reply = manager->get(QNetworkRequest(url));
     34     //readyRead()信号继承自QIODevice类,每当有新的数据可以读取时,都会发射该信号
     35     connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
     36 
     37     //每当网络请求的下载进度更新时都会发射downloadProgress()信号,用于更新进度条;
     38     connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,
     39             SLOT(updateDataReadProgress(qint64,qint64)));
     40 
     41     //每当应答处理结束时,都会发射finished()信号
     42     connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
     43 }
     44 
     45 void MainWindow::replyFinished(QNetworkReply *reply)
     46 {
     47     QString all = reply->readAll();
     48     ui->textBrowser->setText(all);
     49     reply->deleteLater();
     50 }
     51 
     52 //完成下载后,重新隐藏进度条,删除reply和file对象
     53 void MainWindow::httpFinished()
     54 {
     55     ui->progressBar->hide();
     56     file->flush();
     57     file->close();
     58     reply->deleteLater();
     59     reply = 0;
     60     delete file;
     61     file = 0;
     62 }
     63 
     64 //首先判断是否创建了文件,如果是,则读取返回的所有数据,然后写入文件中.
     65 //该文件示后面的下载按钮单机信号槽中创建并打开的
     66 void MainWindow::httpReadyRead()
     67 {
     68     if(file)
     69     {
     70         file->write(reply->readAll());
     71     }
     72 }
     73 
     74 //设置进度条的最大值和当前值
     75 void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
     76 {
     77     ui->progressBar->setMaximum(totalBytes);
     78     ui->progressBar->setValue(bytesRead);
     79 }
     80 
     81 //使用要下载的文件名创建了本地文件,使用输入的url进行网络请求,并显示进度条
     82 void MainWindow::on_pushButton_clicked()
     83 {
     84     url = ui->lineEdit->text();
     85     QFileInfo info(url.path());
     86     QString fileName(info.fileName());
     87     qDebug() << fileName<<endl;
     88     file = new QFile(fileName);
     89 
     90     if(!file->open(QIODevice::WriteOnly))
     91     {
     92         qDebug()<<"file open error";
     93         delete file;
     94         file = 0;
     95         return;
     96     }
     97     startRequest(url);
     98     ui->progressBar->setValue(0);
     99     ui->progressBar->show();
    100 }
  • 相关阅读:
    常见算法:C语言求最小公倍数和最大公约数三种算法
    java数据结构
    创建与删除索引
    Delphi 2007体验!
    wxWindows
    Android中WebView的相关使用
    IAR FOR ARM 各版本号,须要的大家能够收藏了
    [AngularJS] $interval
    [ES6] 10. Array Comprehensions
    [ES6] 09. Destructuring Assignment -- 2
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8831465.html
Copyright © 2011-2022 走看看