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()+"\n"; 66 //获得网络接口的名称 67 detail=detail+tr("硬件地址:")+interface.hardwareAddress()+"\n"; 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+"\t"+tr("IP地址: ")+entry.ip().toString()+"\n"; 80 detail=detail+"\t"+tr("子网掩码: ")+entry.netmask().toString()+"\n"; 81 detail=detail+"\t"+tr("广播地址: ")+entry.broadcast().toString()+"\n"; 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 }