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. namespace Ui {
    15. class Widget;
    16. }
    17.  
    18. class Widget : public QWidget
    19. {
    20. Q_OBJECT
    21.  
    22. public:
    23. explicit Widget(QWidget *parent = );
    24. ~Widget();
    25.  
    26. private:
    27. QLabel *hostLabel;
    28. QLineEdit *LineEditLocalHostName;
    29. QLabel *ipLabel;
    30. QLineEdit *LineEditAddress;
    31.  
    32. QPushButton *detailBtn;
    33.  
    34. QGridLayout *mainLayout;
    35.  
    36. private:
    37. Ui::Widget *ui;
    38.  
    39. public:
    40. void getHostInformation();

    41. public slots:
    42. void slotDetail();
    43. };
    44.  
    45. #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,,);
    18. mainLayout->addWidget(LineEditLocalHostName,,);
    19. mainLayout->addWidget(ipLabel,,);
    20. mainLayout->addWidget(LineEditAddress,,);
    21. //第二行第0个,占两列
    22. mainLayout->addWidget(detailBtn,,,,);
    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. 37 QString localHostName = QHostInfo::localHostName();
    38. LineEditLocalHostName->setText(localHostName);
    39.  
    40. //根据主机名获得相关主机信息,包括IP地址等.
    41. //QHostInfo::fromName()函数通过主机名查找IP地址信息
    42. 42 QHostInfo hostInfo = QHostInfo::fromName(localHostName);

    43. //获得主机的IP地址列表
    44. QList<QHostAddress> listAddress = hostInfo.addresses();
    45.  
    46. //在不为空的情况下,使用第一个IP地址
    47. if(!listAddress.isEmpty())
    48. {
    49. LineEditAddress->setText(listAddress.first().toString());
    50. }
    51. }
    52.  
    53. void Widget::slotDetail()
    54. {
    55. QString detail="";
    56. //QNetworkInterface类提供了一个IP地址和网络接口的列表
    57. QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
    58.  
    59. for(int i=;i<list.count();i++)
    60. {
    61. QNetworkInterface interface=list.at(i);
    62.  
    63. //获得网络接口的名称
    64. detail=detail+tr("设备: ")+interface.name()+"\n";
    65. //获得网络接口的名称
    66. detail=detail+tr("硬件地址:")+interface.hardwareAddress()+"\n";

    67. //每个网络接口包括0个或多个IP地址,
    68. //每个IP地址有选择性地与一个子网掩码和一个广播地址相关联
    69. //QNetworkAddressEntry类存储了被网络接口支持的一个IP地址,
    70. //同时还包括与之相关的子网掩码和广播地址
    71. 73 QList<QNetworkAddressEntry> entryList=interface.addressEntries();
    72.  
    73. for(int j=;j<entryList.count();j++)
    74. {
    75. QNetworkAddressEntry entry = entryList.at(j);
    76. detail=detail+"\t"+tr("IP地址: ")+entry.ip().toString()+"\n";
    77. detail=detail+"\t"+tr("子网掩码: ")+entry.netmask().toString()+"\n";
    78. detail=detail+"\t"+tr("广播地址: ")+entry.broadcast().toString()+"\n";
    79. }
    80. QMessageBox::information(this,tr("Detail"),detail);
    81. }
    82. }
  • 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 = ,Qt::WindowFlags f=);
  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. #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 = ;
    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();
    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=;
    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 = );
    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 = ;
    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 = );
    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,,,,);
    21. mainLayout->addWidget(PortLabe,,);
    22. mainLayout->addWidget(PortLineEdit,,);
    23. mainLayout->addWidget(CreateBtn,,,,);
    24.  
    25. port=;
    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=,int port=);
    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=;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=;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=);
    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()>)
    22. {
    23. int length = bytesAvailable();
    24. char buf[];
    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 = );
    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. #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,,,,);
    32. mainLayout->addWidget(sendLineEdit,,);
    33. mainLayout->addWidget(sendBtn,,);
    34. mainLayout->addWidget(userNameLabel,,);
    35. mainLayout->addWidget(userNameLineEdit,,);
    36. mainLayout->addWidget(serverIPLabel,,);
    37. mainLayout->addWidget(serverIPLineEdit,,);
    38. mainLayout->addWidget(portLabel,,);
    39. mainLayout->addWidget(portLineEdit,,);
    40. mainLayout->addWidget(enterBtn,,,,);
    41.  
    42. status = false;
    43.  
    44. port = ;
    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 = ;
    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=;
    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()>)
    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 = );
    20. ~MainWindow();
    21.  
    22. private slots:
    23. void replyFinished(QNetworkReply *);
    24.  
    25. private:
    26. Ui::MainWindow *ui;
    27.  
    28. QNetworkAccessManager *manager;
    29. };
    30.  
    31. #endif // MAINWINDOW_H
  • mainwindow.cpp
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. #include <QtNetwork>
    5.  
    6. MainWindow::MainWindow(QWidget *parent) :
    7. QMainWindow(parent),
    8. ui(new Ui::MainWindow)
    9. {
    10. ui->setupUi(this);
    11.  
    12. //创建QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后
    13. //管理了管理器的finished()信号和自定义的槽,每当网络应答结束时都会发射
    14. //这个信号.最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest
    15. //类表示,get()函数返回一个QNetworkReply对象
    16. manager = new QNetworkAccessManager(this);
    17. connect(manager,SIGNAL(finished(QNetworkReply*)),this,
    18. SLOT(replyFinished(QNetworkReply*)));
    19. manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
    20. }
    21.  
    22. MainWindow::~MainWindow()
    23. {
    24. delete ui;
    25. }
    26.  
    27. void MainWindow::replyFinished(QNetworkReply *reply)
    28. {
    29. QString all = reply->readAll();
    30. ui->textBrowser->setText(all);
    31. reply->deleteLater();
    32. }
  • 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 = );
  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. void on_pushButton_clicked();
  34.  
  35. private:
  36. Ui::MainWindow *ui;
  37.  
  38. QNetworkAccessManager *manager;
  39.  
  40. QNetworkReply *reply;
  41. QUrl url;
  42. QFile *file;
  43. };
  44.  
  45. #endif // MAINWINDOW_H

mainwindow.cpp

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

37.Qt网络与通信的更多相关文章

  1. QT实现TCP通信服务器端和客户端(支持多个客户端)精简版

    上星期接了个私活,工期两星期,报酬3000,写一个小软件,采集定向网络上的数据,并进行双向通信,捣鼓了两天,终于把QT中tcp通信这块调通了,找过N多例子,绝大部分都是基本的一个服务端一个客户端通信的 ...

  2. Android网络请求通信之Volley

    一.Volley简介 Volley网络框架是Google公司在2013年发布的一款Android平台上的网络请求通信库.以下是对Volley的简单归纳. Volley的优点: 使网络通信更快.更简单. ...

  3. Qt 与 JavaScript 通信

    使用QWebView加载网页后,解决Qt与JavaScript通信的问题: The QtWebKit Bridge :http://qt-project.org/doc/qt-4.8/qtwebkit ...

  4. Qt网络编程QTcpServer和QTcpSocket的理解

    前一段时间通过调试Qt源码,大致了解了Qt的事件机制.信号槽机制.毕竟能力和时间有限.有些地方理解的并不是很清楚. 开发环境:Linux((fedora 17),Qt版本(qt-everywhere- ...

  5. bbblack的网络socket通信实验

    1. 本次用bbblack作网络的通信实验,对了,这个板子必须装SD卡才能启动吗?板载的4GB eMMC Flash 存储器,eMMC (Embedded Multi Media Card) 为MMC ...

  6. Qt实现串口通信总结

    Qt实现串口通信总结 注意: Qt5发布之前,Qt实现串口通信一般是采用第三方类库qextserialport.Qt5发布后自带了QtSerialPort 能够支持串口通信. 1.Qextserial ...

  7. (转) 在linux网络UDP通信中,关于客户端是否绑定的理解

    最近在做一个实例,是用RTSP协议完成.服务器已经有了,只需要把客户端做好就行了,在做的过程中发现了一些问题,就是关于UDP客户端是否绑定的问题. 也许大家在书上看到的大多都是说UDP客户端不需要绑定 ...

  8. qt 网络库使用介绍

    qt 网络库使用介绍 在.pro文件中,要手动添加network模块:QT += network 有三个核心类, QNetworkAccessManager: 发送get或者post请求. 用get方 ...

  9. 书.Windows网络与通信程序设计

    1.PDF&源码 保存到了 我的网盘fivez79513-->"PDF&源码" 目录中 “Windows网络与通信程序设计(第2版) 完整带书签PDF+源码. ...

随机推荐

  1. [Offer收割]编程练习赛38

    漏写的数字 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #inclu ...

  2. 关于KO信息

    最近写大论文查到KO也是可以用于分类的一种信息. 如何使用KEGG进行通路富集http://blog.sciencenet.cn/blog-364884-779116.html kegg 数据库学习笔 ...

  3. HDFS与java API应用

    java代码操作hadoop文件需要用hadoop的jar包,comment,hdfs,yarn,mapreduce,内均有有关jar包,eclipse操作hadoop还需要配置core-site.x ...

  4. Android 自定义控件——图片剪裁

    如图: 思路:在一个自定义View上绘制一张图片(参照前面提到的另一篇文章),在该自定义View上绘制一个自定义的FloatDrawable,也就是图中的浮层.绘制图片和FloatDrawable的交 ...

  5. MIME类型记录

    Content-Disposition: attachment; filename="filename.xls" 提供下载

  6. 原生sql的各种问题

    1.nutz有方法自动根据数据库建models吗?2.select * from a a没有建相应的models怎么取结果?3.可以直接操作result,而不是在callback里面设置吗? wend ...

  7. Java中的常量

    常量的概念 是指在Java程序中固定不变的数据.我们可以理解为是一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变. 常量的分类 整数常量:  所有的整数   例如 100 -100 123 ...

  8. java 常用API 包装 练习

    package com.oracel.demo01; import java.util.Random; public class Swzy { public static void main(Stri ...

  9. 如何添加删除子网卡eth0:1(linux案例)

    这种方法实现了单网卡多IP,我的系统是centos7的,如何添加删除子网卡IP详细请看下面操作例子 添加子网卡IP:ifconfig  ens3:1  192.168.0.100/24        ...

  10. Mysql插入语句.txt

    INSERT INTO 目标表 SELECT * FROM 来源表;比如要将 articles 表插入到 newArticles 表中,则是:INSERT INTO newArticles SELEC ...