37.Qt网络与通信
1 获取本机网络与通信
在网络应用中,经常需要获得本机的主机名.IP地址和硬件地址等网络信息.运用QHostInfo,QNetWorkInterface,QNetworkAddressEntry可获得本机的网络信息.
- widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
- #include <QWidget>
- #include <QLabel>
- #include <QPushButton>
- #include <QLineEdit>
- #include <QGridLayout>
- #include <QMessageBox>
- #include <QHostInfo>
- #include <QNetworkInterface>
- namespace Ui {
- class Widget;
- }
- class Widget : public QWidget
- {
- Q_OBJECT
- public:
- explicit Widget(QWidget *parent = );
- ~Widget();
- private:
- QLabel *hostLabel;
- QLineEdit *LineEditLocalHostName;
- QLabel *ipLabel;
- QLineEdit *LineEditAddress;
- QPushButton *detailBtn;
- QGridLayout *mainLayout;
- private:
- Ui::Widget *ui;
- public:
- void getHostInformation();
- public slots:
- void slotDetail();
- };
- #endif // WIDGET_H
- #ifndef WIDGET_H
- widget.cpp
- #include "widget.h"
- #include "ui_widget.h"
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- hostLabel = new QLabel(tr("主机名: "));
- LineEditLocalHostName = new QLineEdit;
- ipLabel = new QLabel(tr("IP 地址:"));
- LineEditAddress = new QLineEdit;
- detailBtn = new QPushButton(tr("详细"));
- mainLayout = new QGridLayout(this);
- mainLayout->addWidget(hostLabel,,);
- mainLayout->addWidget(LineEditLocalHostName,,);
- mainLayout->addWidget(ipLabel,,);
- mainLayout->addWidget(LineEditAddress,,);
- //第二行第0个,占两列
- mainLayout->addWidget(detailBtn,,,,);
- getHostInformation();
- connect(detailBtn,SIGNAL(clicked(bool)),this,SLOT(slotDetail()));
- }
- Widget::~Widget()
- {
- delete ui;
- }
- void Widget::getHostInformation()
- {
- //获得本机主机名.QHostInfo提供了一系列有关网络信息的静态函数,
- //可以根据主机名获得分配的IP地址,也可以根据IP地址获得相应的主机名
- 37 QString localHostName = QHostInfo::localHostName();
- LineEditLocalHostName->setText(localHostName);
- //根据主机名获得相关主机信息,包括IP地址等.
- //QHostInfo::fromName()函数通过主机名查找IP地址信息
- 42 QHostInfo hostInfo = QHostInfo::fromName(localHostName);
- //获得主机的IP地址列表
- QList<QHostAddress> listAddress = hostInfo.addresses();
- //在不为空的情况下,使用第一个IP地址
- if(!listAddress.isEmpty())
- {
- LineEditAddress->setText(listAddress.first().toString());
- }
- }
- void Widget::slotDetail()
- {
- QString detail="";
- //QNetworkInterface类提供了一个IP地址和网络接口的列表
- QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
- for(int i=;i<list.count();i++)
- {
- QNetworkInterface interface=list.at(i);
- //获得网络接口的名称
- detail=detail+tr("设备: ")+interface.name()+"\n";
- //获得网络接口的名称
- detail=detail+tr("硬件地址:")+interface.hardwareAddress()+"\n";
- //每个网络接口包括0个或多个IP地址,
- //每个IP地址有选择性地与一个子网掩码和一个广播地址相关联
- //QNetworkAddressEntry类存储了被网络接口支持的一个IP地址,
- //同时还包括与之相关的子网掩码和广播地址
- 73 QList<QNetworkAddressEntry> entryList=interface.addressEntries();
- for(int j=;j<entryList.count();j++)
- {
- QNetworkAddressEntry entry = entryList.at(j);
- detail=detail+"\t"+tr("IP地址: ")+entry.ip().toString()+"\n";
- detail=detail+"\t"+tr("子网掩码: ")+entry.netmask().toString()+"\n";
- detail=detail+"\t"+tr("广播地址: ")+entry.broadcast().toString()+"\n";
- }
- QMessageBox::information(this,tr("Detail"),detail);
- }
- }
- #include "widget.h"
- main.cpp
- #include "widget.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- Widget w;
- w.show();
- return a.exec();
- }
- #include "widget.h"
2 基于UDP的网络广播程序
2.1 UDP(user data protocol)是一种简单轻量级,不可靠,面向数据报无连接的传输协议,可以用在不是十分重要的场合
2.2 UDP编程模型
在UDP方式下客户端并不与服务器建立连接,它只负责调用发送函数向服务器法术数据报.类似的服务器不从客户端接收连接,只负责调用接收函数,等待来自某客户端的数据到达.Qt中通过QUdpSocket类实现UDP协议的编程.
服务器端:
- udpserver.h
- #ifndef UDPSERVER_H
- #define UDPSERVER_H
- #include <QDialog>
- #include <QLabel>
- #include <QPushButton>
- #include <QVBoxLayout>
- #include <QLineEdit>
- #include <QUdpSocket>
- #include <QTimer>
- namespace Ui {
- class UdpServer;
- }
- class UdpServer : public QDialog
- {
- Q_OBJECT
- public:
- explicit UdpServer(QWidget *parent = ,Qt::WindowFlags f=);
- ~UdpServer();
- public slots:
- void StartBtnClicked();
- void timeout();
- private:
- int port;
- bool isStarted;
- QUdpSocket *udpSocket;
- QTimer *timer;
- private:
- QLabel *TimerLabel;
- QLineEdit *TextLineEdit;
- QPushButton *StartBtn;
- QVBoxLayout *mainLayout;
- private:
- Ui::UdpServer *ui;
- };
- #endif // UDPSERVER_H
- udpserver.cpp
- #include "udpserver.h"
- #include "ui_udpserver.h"
- #include <QHostAddress>
- UdpServer::UdpServer(QWidget *parent,Qt::WindowFlags f) :
- QDialog(parent,f),
- ui(new Ui::UdpServer)
- {
- ui->setupUi(this);
- setWindowTitle(tr("UDP 服务器"));
- TimerLabel = new QLabel(tr("计时器:"),this);
- TextLineEdit = new QLineEdit(this);
- StartBtn = new QPushButton(tr("开始"),this);
- //设置垂直布局
- mainLayout = new QVBoxLayout(this);
- mainLayout->addWidget(TimerLabel);
- mainLayout->addWidget(TextLineEdit);
- mainLayout->addWidget(StartBtn);
- connect(StartBtn,SIGNAL(clicked(bool)),this,SLOT(StartBtnClicked()));
- //设置UDP的端口号参数,服务器定时向此端口发送广播消息
- port = ;
- isStarted = false;
- udpSocket = new QUdpSocket(this);
- //创建定时器
- timer = new QTimer(this);
- //定时发送广播消息
- connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
- }
- UdpServer::~UdpServer()
- {
- delete ui;
- }
- void UdpServer::StartBtnClicked()
- {
- //打开
- if(!isStarted)
- {
- StartBtn->setText(tr("停止"));
- //每隔1000秒发送一个消息
- timer->start();
- isStarted=true;
- }
- else
- {
- StartBtn->setText(tr("开始"));
- isStarted = false;
- timer->stop();
- }
- }
- void UdpServer::timeout()
- {
- QString msg = TextLineEdit->text();
- int length=;
- if(msg=="")
- {
- return;
- }
- //QHostAddress::Broadcast 指定向广播地址发送
- if(length=udpSocket->writeDatagram(msg.toLatin1(),
- msg.length(),QHostAddress::Broadcast,port)!=msg.length())
- {
- return;
- }
- }
- #include "udpserver.h"
- udpclient.h
- #ifndef UDPCLIENT_H
- #define UDPCLIENT_H
- #include <QDialog>
- #include <QVBoxLayout>
- #include <QTextEdit>
- #include <QPushButton>
- #include <QUdpSocket>
- namespace Ui {
- class UdpClient;
- }
- class UdpClient : public QDialog
- {
- Q_OBJECT
- public:
- explicit UdpClient(QWidget *parent = );
- ~UdpClient();
- public slots:
- void CloseBtnClicked();
- void dataReceived();
- private:
- int port;
- QUdpSocket *udpSocket;
- private:
- Ui::UdpClient *ui;
- QTextEdit *ReceiveTextEdit;
- QPushButton *closeBtn;
- QVBoxLayout *mainLayout;
- };
- #endif // UDPCLIENT_H
- #ifndef UDPCLIENT_H
- udpclient.cpp
- #include "udpclient.h"
- #include "ui_udpclient.h"
- #include <QMessageBox>
- #include <QHostAddress>
- UdpClient::UdpClient(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::UdpClient)
- {
- ui->setupUi(this);
- setWindowTitle(tr("UDP 客户端"));
- ReceiveTextEdit = new QTextEdit(this);
- closeBtn = new QPushButton(tr("关闭"),this);
- mainLayout = new QVBoxLayout(this);
- mainLayout->addWidget(ReceiveTextEdit);
- mainLayout->addWidget(closeBtn);
- connect(closeBtn,SIGNAL(clicked(bool)),this,SLOT(CloseBtnClicked()));
- //设置UDP的端口号参数,指定在此端口上监听数据
- port = ;
- //创建一个QUdpSocket
- udpSocket = new QUdpSocket(this);
- //连接QIODevice的readyRead()信号
- //QUdpSocket也是一个I/O设备,从QIODevice继承而来,当有数据到达I/O设备时,发出readyRead()信号
- connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
- //绑定到指定的端口上
- bool result=udpSocket->bind(port);
- if(!result)
- {
- QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
- return;
- }
- }
- UdpClient::~UdpClient()
- {
- delete ui;
- }
- void UdpClient::CloseBtnClicked()
- {
- close();
- }
- void UdpClient::dataReceived()
- {
- //判断UdpSocket中是否有数据报可读
- //hasPendingDatagrams()方法在至少有一个数据报可读时返回true
- while(udpSocket->hasPendingDatagrams())
- {
- //实现读取第一个数据报
- //pendingDataSize()可以获得第一个数据报的长度
- QByteArray datagram;
- datagram.resize(udpSocket->pendingDatagramSize());
- udpSocket->readDatagram(datagram.data(),datagram.size());
- QString msg = datagram.data();
- //显示数据内容
- ReceiveTextEdit->insertPlainText(msg);
- }
- }
- #include "udpclient.h"
3 基于TCP的网络聊天室程序
TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地送达网络上的其他计算机.因此,对可靠性要求高的数据通信系统往往使用TCP协议传输数据,但在正则收发数据前通信双方必须首先建立连接.
首先启动服务器,一段时间后启动客户端,它与此服务器经过三次握手后建立连接.此后的一段时间内,客户端向服务器发送一个请求,服务器处理这个请求,并为客户端发回一个响应.这个过程一直持续下去,知道客户端为服务器发一个文件结束符,并关闭客户端连接,接着服务器也关闭服务器的连接,结束运行或等待一个新的客户端连接.
Qt中通过QTcpSocket类实现TCP协议的编程.
代码示例:
服务器端
- tcpserver.h
- #ifndef TCPSERVER_H
- #define TCPSERVER_H
- #include <QDialog>
- #include <QListWidget>
- #include <QLabel>
- #include <QLineEdit>
- #include <QPushButton>
- #include <QGridLayout>
- #include "serverh.h"
- namespace Ui {
- class TcpServer;
- }
- class TcpServer : public QDialog
- {
- Q_OBJECT
- public:
- explicit TcpServer(QWidget *parent = );
- ~TcpServer();
- private:
- Ui::TcpServer *ui;
- QListWidget *ContentListWidget;
- QLabel *PortLabe;
- QLineEdit *PortLineEdit;
- QPushButton *CreateBtn;
- QGridLayout *mainLayout;
- private:
- int port;
- serverh *server;
- public slots:
- void slotCreateServer();
- void updateServer(QString,int);
- };
- #endif // TCPSERVER_H
- #ifndef TCPSERVER_H
- tcpserver.cpp
- #include "tcpserver.h"
- #include "ui_tcpserver.h"
- TcpServer::TcpServer(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::TcpServer)
- {
- ui->setupUi(this);
- setWindowTitle(tr("TCP Server"));
- ContentListWidget = new QListWidget;
- PortLabe = new QLabel(tr("端口: "));
- PortLineEdit = new QLineEdit();
- CreateBtn = new QPushButton(tr("创建聊天室"));
- mainLayout=new QGridLayout(this);
- mainLayout->addWidget(ContentListWidget,,,,);
- mainLayout->addWidget(PortLabe,,);
- mainLayout->addWidget(PortLineEdit,,);
- mainLayout->addWidget(CreateBtn,,,,);
- port=;
- PortLineEdit->setText(QString::number(port));
- connect(CreateBtn,SIGNAL(clicked(bool)),this,SLOT(slotCreateServer()));
- }
- TcpServer::~TcpServer()
- {
- delete ui;
- }
- void TcpServer::slotCreateServer()
- {
- //创建一个serverh对象
- server = new serverh(this,port);
- //将serverh对象的updateServer()信号与相应的槽函数进行连接
- connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
- CreateBtn->setEnabled(false);
- }
- void TcpServer::updateServer(QString msg , int length)
- {
- ContentListWidget->addItem(msg.left(length));
- }
- #include "tcpserver.h"
- server.h
- #ifndef SERVERH_H
- #define SERVERH_H
- #include <QTcpServer>
- #include <QObject>
- #include "tcpclientsocket.h"//包含TCP的套接字
- class serverh : public QTcpServer
- {
- Q_OBJECT
- public:
- serverh(QObject *parent=,int port=);
- //用来保存与每一个客户端连接的TcpClientSocket
- QList<tcpclientsocket*> tcpClientSocketList;
- signals:
- void updateServer(QString,int);
- public slots:
- void updateClients(QString,int);
- void slotDisconnected(int);
- protected:
- void incomingConnection(int socketDescriptor);
- };
- #endif // SERVERH_H
- #ifndef SERVERH_H
server.cpp
- #include "serverh.h"
- serverh::serverh(QObject *parent,int port):QTcpServer(parent)
- {
- //在指定的端口对任意地址进行监听
- //QHostAddress定义了几种特殊的IP地址
- //QHostAddress定义了几种特殊的IP地址,QHostAddress::Null表示一个空的地址
- //QHostAddress::LocalHost表示IPV4的本机地址127.0.0.1
- //QHostAddress::LocalHostIPV6表示IPv6的本机地址
- //QHostAddress::Broadcast表示广播地址255.255.255.255
- //QHostAddress::Any表示Ipv4的任意地址0.0.0.0
- //QHostAddress::AnyIPv6表示IPv6的任意地址
- listen(QHostAddress::Any,port);
- }
- //当出现一个新的连接时,QTcpServer触发incomingConnection()函数,参数
- //socketDescriptor指定连接的Socket描述符
- void serverh::incomingConnection(int socketDescriptor)
- {
- qDebug() << "receive connect" << endl;
- //创建一个新的TcpClientSocket客户端通信
- tcpclientsocket *tcpClientSocket = new tcpclientsocket(this);
- //连接TcpClientSocket的updateClients信号
- connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,
- SLOT(updateClients(QString,int)));
- //连接TcpClientSocket的disconnect信号
- connect(tcpClientSocket,SIGNAL(disconnected(int)),this,
- SLOT(slotDisconnected(int)));
- //将tcpClient加入客户端套接字列表以便管理
- tcpClientSocket->setSocketDescriptor(socketDescriptor);
- tcpClientSocketList.append(tcpClientSocket);
- }
- void serverh::updateClients(QString msg, int length)
- {
- //发出updateServer信号,来通知服务器对话框更新相应的显示状态
- qDebug() << msg << endl;
- emit updateServer(msg,length);
- qDebug() << msg << endl;
- for(int i=;i<tcpClientSocketList.count();i++)
- {
- QTcpSocket *item = tcpClientSocketList.at(i);
- if(item->write(msg.toLatin1(),length)!=length)
- {
- continue;
- }
- }
- }
- void serverh::slotDisconnected(int descriptor)
- {
- for(int i=;i<tcpClientSocketList.count();i++)
- {
- QTcpSocket *item = tcpClientSocketList.at(i);
- if(item->socketDescriptor()==descriptor)
- {
- tcpClientSocketList.removeAt(i);
- return;
- }
- }
- return;
- }
- tcpclientsocket.h
- #ifndef TCPCLIENTSOCKET_H
- #define TCPCLIENTSOCKET_H
- #include <QTcpSocket>
- #include <QObject>
- class tcpclientsocket : public QTcpSocket
- {
- Q_OBJECT //添加宏是为了实现信号和槽的通信
- public:
- tcpclientsocket(QObject *parent=);
- signals:
- void updateClients(QString ,int);
- void disconnected(int);
- protected slots:
- void dataReceived();
- void slotDisconnected();
- };
- #endif // TCPCLIENTSOCKET_H
- #ifndef TCPCLIENTSOCKET_H
- tcpclientsocket.cpp
- #include "tcpclientsocket.h"
- #include <QDebug>
- tcpclientsocket::tcpclientsocket(QObject *parent)
- {
- //指定信号与槽的连接关系
- //readyRead()是QIODevice的signal,由QTcpSocket继承而来.QIODevice
- //是所有输入/输出设备的一个抽象类,其中定义了基本的接口,在Qt中,QTcpSocket也被
- //看做一个QIODevice,readyRead()信号在有数据到来时发出
- connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
- //信号在断开连接时发出
- connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
- }
- //当有数据到来的时候触发dataReceived()函数,从套接字中将有效数据取出,然后
- //发出updateClients()信号.
- //updateClients()信号是通知服务器向聊天室内的所有成员广播信息
- void tcpclientsocket::dataReceived()
- {
- qDebug() << "accept message" << endl;
- while(bytesAvailable()>)
- {
- int length = bytesAvailable();
- char buf[];
- read(buf,length);
- qDebug() << buf << endl;
- QString msg=buf;
- qDebug() << msg << endl;
- emit updateClients(msg,length);
- }
- }
- //槽函数slotDisconnected
- void tcpclientsocket::slotDisconnected()
- {
- emit disconnected(this->socketDescriptor());
- }
- #include "tcpclientsocket.h"
客户端
- tcpclient.h
- #ifndef TCPCLIENT_H
- #define TCPCLIENT_H
- #include <QDialog>
- namespace Ui {
- class TcpClient;
- }
- #include <QDialog>
- #include <QListWidget>
- #include <QLineEdit>
- #include <QPushButton>
- #include <QLabel>
- #include <QGridLayout>
- #include <QHostAddress>
- #include <QTcpSocket>
- class TcpClient : public QDialog
- {
- Q_OBJECT
- public:
- explicit TcpClient(QWidget *parent = );
- ~TcpClient();
- private:
- Ui::TcpClient *ui;
- QListWidget *contentListWidget;
- QLineEdit *sendLineEdit;
- QPushButton *sendBtn;
- QLabel *userNameLabel;
- QLineEdit *userNameLineEdit;
- QLabel *serverIPLabel;
- QLineEdit *serverIPLineEdit;
- QLabel *portLabel;
- QLineEdit *portLineEdit;
- QPushButton *enterBtn;
- QGridLayout *mainLayout;
- private:
- bool status;
- int port;
- QHostAddress *serverIP;
- QString userName;
- QTcpSocket *tcpSocket;
- private slots:
- void slotEnter();
- void slotConnected();
- void slotDisconnected();
- void dataReceived();
- void slotSend();
- };
- #endif // TCPCLIENT_H
- #ifndef TCPCLIENT_H
- tcpclient.cpp
- #include "tcpclient.h"
- #include "ui_tcpclient.h"
- #include <QMessageBox>
- #include <QHostInfo>
- TcpClient::TcpClient(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::TcpClient)
- {
- ui->setupUi(this);
- setWindowTitle(tr("TCP Client"));
- contentListWidget = new QListWidget;
- sendLineEdit = new QLineEdit;
- sendBtn = new QPushButton(tr("发送"));
- userNameLabel=new QLabel(tr("用户名:"));
- userNameLineEdit = new QLineEdit;
- serverIPLabel = new QLabel(tr("服务器地址: "));
- serverIPLineEdit = new QLineEdit;
- portLabel = new QLabel(tr("端口: "));
- portLineEdit = new QLineEdit;
- enterBtn = new QPushButton(tr("进入聊天室"));
- mainLayout = new QGridLayout(this);
- mainLayout->addWidget(contentListWidget,,,,);
- mainLayout->addWidget(sendLineEdit,,);
- mainLayout->addWidget(sendBtn,,);
- mainLayout->addWidget(userNameLabel,,);
- mainLayout->addWidget(userNameLineEdit,,);
- mainLayout->addWidget(serverIPLabel,,);
- mainLayout->addWidget(serverIPLineEdit,,);
- mainLayout->addWidget(portLabel,,);
- mainLayout->addWidget(portLineEdit,,);
- mainLayout->addWidget(enterBtn,,,,);
- status = false;
- port = ;
- portLineEdit->setText(QString::number(port));
- serverIP=new QHostAddress();
- connect(enterBtn,SIGNAL(clicked(bool)),this,SLOT(slotEnter()));
- connect(sendBtn,SIGNAL(clicked(bool)),this,SLOT(slotSend()));
- sendBtn->setEnabled(false);
- }
- TcpClient::~TcpClient()
- {
- delete ui;
- }
- void TcpClient::slotEnter()
- {
- //status表示当前的状态,true表示已经进入聊天室,false表示已经离开聊天室
- //这里根据status的状态决定是进入还是离开操作
- if(!status)
- {
- //完成输入合法性检验
- QString ip = serverIPLineEdit->text();
- //用来判断给定的IP地址是否能够被正确解析
- if(!serverIP->setAddress(ip))
- {
- QMessageBox::information(this,tr("error"),tr("server ip address error!"));
- return;
- }
- if(userNameLineEdit->text()=="")
- {
- QMessageBox::information(this,tr("error"),tr("User name error!"));
- return;
- }
- userName = userNameLineEdit->text();
- //创建QTcpSocket类对象,并将信号/槽连接起来
- tcpSocket = new QTcpSocket(this);
- connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));
- connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
- connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
- //与TCP服务器端连接,连接成功后发出connected
- tcpSocket->connectToHost(*serverIP,port);
- status = true;
- }
- else
- {
- int length = ;
- //构建一条离开聊天室的消息
- QString msg = userName + tr(":Leave Chat Room");
- //通知服务器端以上构造的消息
- if( ( length=tcpSocket->write( msg.toLatin1(),msg.length() ) )!=msg.length())
- {
- return;
- }
- //与服务器端口连接,断开后发出disconnected()信号
- tcpSocket->disconnectFromHost();
- //将status状态复位
- status = false;
- }
- }
- //当服务器连上成功后,客户端构造一条进入聊天室的消息,并通知服务器
- void TcpClient::slotConnected()
- {
- qDebug() << "进入服务器" << endl;
- sendBtn->setEnabled(true);
- enterBtn->setText(tr("离开"));
- int length=;
- QString msg = userName+tr("Enter Chat Room");
- if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())
- {
- qDebug() << "发送失败" << endl;
- return;
- }
- else
- {
- qDebug() << "发送成功" << endl;
- }
- }
- void TcpClient::slotDisconnected()
- {
- sendBtn->setEnabled(false);
- enterBtn->setText(tr("进入聊天室"));
- }
- //当有数据到来时触发此函数,从套接字中将有效数据提出并显示
- void TcpClient::dataReceived()
- {
- while(tcpSocket->bytesAvailable()>)
- {
- QByteArray datagram;
- datagram.resize(tcpSocket->bytesAvailable());
- tcpSocket->read(datagram.data(),datagram.size());
- QString msg = datagram.data();
- contentListWidget->addItem(msg.left(datagram.size()));
- }
- }
- void TcpClient::slotSend()
- {
- if(sendLineEdit->text()=="")
- {
- return;
- }
- QString msg=userName+":"+sendLineEdit->text();
- tcpSocket->write(msg.toLatin1(),msg.length());
- sendLineEdit->clear();
- }
- #include "tcpclient.h"
- main.cpp
- #include "tcpclient.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- TcpClient w;
- w.show();
- return a.exec();
- }
- #include "tcpclient.h"
4 网页浏览实例
首先创建一个QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后关联了管理器的finished信号和自定义的槽,每当网络应答结束时都会发射这个信号.最后使用了get函数来发送一个网络请求,网络请求使用QNetwrokRequest类表示,get()函数返回一个QNetworkReply对象
- mainwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QNetworkReply>
- #include <QNetworkAccessManager>
- class QNetworkAccessManager;
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = );
- ~MainWindow();
- private slots:
- void replyFinished(QNetworkReply *);
- private:
- Ui::MainWindow *ui;
- QNetworkAccessManager *manager;
- };
- #endif // MAINWINDOW_H
- #ifndef MAINWINDOW_H
- mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QtNetwork>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- //创建QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后
- //管理了管理器的finished()信号和自定义的槽,每当网络应答结束时都会发射
- //这个信号.最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest
- //类表示,get()函数返回一个QNetworkReply对象
- manager = new QNetworkAccessManager(this);
- connect(manager,SIGNAL(finished(QNetworkReply*)),this,
- SLOT(replyFinished(QNetworkReply*)));
- manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::replyFinished(QNetworkReply *reply)
- {
- QString all = reply->readAll();
- ui->textBrowser->setText(all);
- reply->deleteLater();
- }
- #include "mainwindow.h"
- main.cpp
- #include "mainwindow.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
- #include "mainwindow.h"
- 文件下载示例
mianwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QNetworkReply>
- #include <QNetworkAccessManager>
- class QNetworkAccessManager;
- #include <QUrl>
- class QFile;
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = );
- ~MainWindow();
- void startRequest(QUrl url);
- private slots:
- void replyFinished(QNetworkReply *);
- void httpFinished();
- void httpReadyRead();
- void updateDataReadProgress(qint64,qint64);
- void on_pushButton_clicked();
- private:
- Ui::MainWindow *ui;
- QNetworkAccessManager *manager;
- QNetworkReply *reply;
- QUrl url;
- QFile *file;
- };
- #endif // MAINWINDOW_H
mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QtNetwork>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- //创建QNetworkAccessManager类的实例,它用来发送网络请求和接收应答.然后
- //管理了管理器的finished()信号和自定义的槽,每当网络应答结束时都会发射
- //这个信号.最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest
- //类表示,get()函数返回一个QNetworkReply对象
- manager = new QNetworkAccessManager(this);
- connect(manager,SIGNAL(finished(QNetworkReply*)),this,
- SLOT(replyFinished(QNetworkReply*)));
- // manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
- //ui->progressBar->hide();
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::startRequest(QUrl url)
- {
- //使用get()函数发送网络请求
- reply = manager->get(QNetworkRequest(url));
- //readyRead()信号继承自QIODevice类,每当有新的数据可以读取时,都会发射该信号
- connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
- //每当网络请求的下载进度更新时都会发射downloadProgress()信号,用于更新进度条;
- connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,
- SLOT(updateDataReadProgress(qint64,qint64)));
- //每当应答处理结束时,都会发射finished()信号
- connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
- }
- void MainWindow::replyFinished(QNetworkReply *reply)
- {
- QString all = reply->readAll();
- ui->textBrowser->setText(all);
- reply->deleteLater();
- }
- //完成下载后,重新隐藏进度条,删除reply和file对象
- void MainWindow::httpFinished()
- {
- ui->progressBar->hide();
- file->flush();
- file->close();
- reply->deleteLater();
- reply = ;
- delete file;
- file = ;
- }
- //首先判断是否创建了文件,如果是,则读取返回的所有数据,然后写入文件中.
- //该文件示后面的下载按钮单机信号槽中创建并打开的
- void MainWindow::httpReadyRead()
- {
- if(file)
- {
- file->write(reply->readAll());
- }
- }
- //设置进度条的最大值和当前值
- void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
- {
- ui->progressBar->setMaximum(totalBytes);
- ui->progressBar->setValue(bytesRead);
- }
- //使用要下载的文件名创建了本地文件,使用输入的url进行网络请求,并显示进度条
- void MainWindow::on_pushButton_clicked()
- {
- url = ui->lineEdit->text();
- QFileInfo info(url.path());
- QString fileName(info.fileName());
- qDebug() << fileName<<endl;
- file = new QFile(fileName);
- if(!file->open(QIODevice::WriteOnly))
- {
- qDebug()<<"file open error";
- delete file;
- file = ;
- return;
- }
- startRequest(url);
- ui->progressBar->setValue();
- ui->progressBar->show();
- }
37.Qt网络与通信的更多相关文章
- QT实现TCP通信服务器端和客户端(支持多个客户端)精简版
上星期接了个私活,工期两星期,报酬3000,写一个小软件,采集定向网络上的数据,并进行双向通信,捣鼓了两天,终于把QT中tcp通信这块调通了,找过N多例子,绝大部分都是基本的一个服务端一个客户端通信的 ...
- Android网络请求通信之Volley
一.Volley简介 Volley网络框架是Google公司在2013年发布的一款Android平台上的网络请求通信库.以下是对Volley的简单归纳. Volley的优点: 使网络通信更快.更简单. ...
- Qt 与 JavaScript 通信
使用QWebView加载网页后,解决Qt与JavaScript通信的问题: The QtWebKit Bridge :http://qt-project.org/doc/qt-4.8/qtwebkit ...
- Qt网络编程QTcpServer和QTcpSocket的理解
前一段时间通过调试Qt源码,大致了解了Qt的事件机制.信号槽机制.毕竟能力和时间有限.有些地方理解的并不是很清楚. 开发环境:Linux((fedora 17),Qt版本(qt-everywhere- ...
- bbblack的网络socket通信实验
1. 本次用bbblack作网络的通信实验,对了,这个板子必须装SD卡才能启动吗?板载的4GB eMMC Flash 存储器,eMMC (Embedded Multi Media Card) 为MMC ...
- Qt实现串口通信总结
Qt实现串口通信总结 注意: Qt5发布之前,Qt实现串口通信一般是采用第三方类库qextserialport.Qt5发布后自带了QtSerialPort 能够支持串口通信. 1.Qextserial ...
- (转) 在linux网络UDP通信中,关于客户端是否绑定的理解
最近在做一个实例,是用RTSP协议完成.服务器已经有了,只需要把客户端做好就行了,在做的过程中发现了一些问题,就是关于UDP客户端是否绑定的问题. 也许大家在书上看到的大多都是说UDP客户端不需要绑定 ...
- qt 网络库使用介绍
qt 网络库使用介绍 在.pro文件中,要手动添加network模块:QT += network 有三个核心类, QNetworkAccessManager: 发送get或者post请求. 用get方 ...
- 书.Windows网络与通信程序设计
1.PDF&源码 保存到了 我的网盘fivez79513-->"PDF&源码" 目录中 “Windows网络与通信程序设计(第2版) 完整带书签PDF+源码. ...
随机推荐
- [Offer收割]编程练习赛38
漏写的数字 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #inclu ...
- 关于KO信息
最近写大论文查到KO也是可以用于分类的一种信息. 如何使用KEGG进行通路富集http://blog.sciencenet.cn/blog-364884-779116.html kegg 数据库学习笔 ...
- HDFS与java API应用
java代码操作hadoop文件需要用hadoop的jar包,comment,hdfs,yarn,mapreduce,内均有有关jar包,eclipse操作hadoop还需要配置core-site.x ...
- Android 自定义控件——图片剪裁
如图: 思路:在一个自定义View上绘制一张图片(参照前面提到的另一篇文章),在该自定义View上绘制一个自定义的FloatDrawable,也就是图中的浮层.绘制图片和FloatDrawable的交 ...
- MIME类型记录
Content-Disposition: attachment; filename="filename.xls" 提供下载
- 原生sql的各种问题
1.nutz有方法自动根据数据库建models吗?2.select * from a a没有建相应的models怎么取结果?3.可以直接操作result,而不是在callback里面设置吗? wend ...
- Java中的常量
常量的概念 是指在Java程序中固定不变的数据.我们可以理解为是一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变. 常量的分类 整数常量: 所有的整数 例如 100 -100 123 ...
- java 常用API 包装 练习
package com.oracel.demo01; import java.util.Random; public class Swzy { public static void main(Stri ...
- 如何添加删除子网卡eth0:1(linux案例)
这种方法实现了单网卡多IP,我的系统是centos7的,如何添加删除子网卡IP详细请看下面操作例子 添加子网卡IP:ifconfig ens3:1 192.168.0.100/24 ...
- Mysql插入语句.txt
INSERT INTO 目标表 SELECT * FROM 来源表;比如要将 articles 表插入到 newArticles 表中,则是:INSERT INTO newArticles SELEC ...