一、QHttp
1、QT的应用层协议
QT为网络操作提供了自己封装的类,例如QFtp和QHttp就提供了应用层的文件传输
QHttp类用于构建http客户端程序,它提供了很多操作,例如最常用的get和post函数。Qhttp采用的是一步工作的方式,当调用的get或者post函数之后会立即返回,这样会加快图形界面的响应
2、构建http下载程序
http下载自然离不开QHttp类,在Qt的网络操作中需要在工程文件中加一句话:QT+=network,否则网络操作会失败的
QHttp的get方法可以让用户从服务器上获取数据,get方法需要提供下载的路径和文件。
在http交互的过程中主要有几个信号会发生:
1、当一个http操作完成时会发出这个信号
requestFinished(int requestId, int error)
2、当从服务器读到数据时会发送这个信号
dataReadProgress(int byteRead, int totalByte)
3、当收到服务器的应答时会发出这个信号
responseHeaderReceived(const QHttpResponseHeader&)
3、实例
二、socket
在LINUX下进行网络编程,我们可以使用LINUX提供的统一的套接字接口。但是这种方法牵涉到太多的结构体,比如IP地址,端口转换等,不熟练的人往往容易犯这样那样的错误。QT中提供的SOCKET完全使用了类的封装机制,使用户不需要接触底层的各种结构体操作
1、传输层协议
传输层协议主要有两种TCP和UDP
Tcp:面向连接的、可靠的、基于字节流的传输层控制协议。TCP可以为应用程序提供可靠的数据传输,从一端发出的数据可以毫无差错的传送到另一端。在传输数据之前双方必须建立连接,对于数据要求高的程序,可以使用TCP传输
Udp:提供无连接的不可靠的报文传输,一般可以用在以下场合:
1)、聊天软件
2)、流媒体数据
3)、视频聊天
2、TCP服务器
TC服务器建立的一般步骤:初始化、绑定、监听、接受连接、传输数据、关闭
1)、Qt提供了QTcpServer类,可以帮组我们建立服务器,这个类继承自 QOBJECT
QTcpServer server = new QTcpServer(this);
2)、使用listen方法来监听
server->listen(ip,port)
3)、nextPendingConnection建立连接,返回QTcpSocket
QTcpSocket socket = server->nextPendingConnection()
4)、写入数据write
socket->write();
3、TCP客户端
TCP客户端建立的一般步骤:初始化套接字、建立连接、数据传输、关闭
1)、创造套接字
QTcpSocket socket = new QTcpSocket();
2)、连接到服务器
socket->connectToHost(ip,port);
3)、传输数据
当有数据来的时候会发出readyRead信号
1、QT的应用层协议
QT为网络操作提供了自己封装的类,例如QFtp和QHttp就提供了应用层的文件传输
QHttp类用于构建http客户端程序,它提供了很多操作,例如最常用的get和post函数。Qhttp采用的是一步工作的方式,当调用的get或者post函数之后会立即返回,这样会加快图形界面的响应
2、构建http下载程序
http下载自然离不开QHttp类,在Qt的网络操作中需要在工程文件中加一句话:QT+=network,否则网络操作会失败的
QHttp的get方法可以让用户从服务器上获取数据,get方法需要提供下载的路径和文件。
在http交互的过程中主要有几个信号会发生:
1、当一个http操作完成时会发出这个信号
requestFinished(int requestId, int error)
2、当从服务器读到数据时会发送这个信号
dataReadProgress(int byteRead, int totalByte)
3、当收到服务器的应答时会发出这个信号
responseHeaderReceived(const QHttpResponseHeader&)
3、实例
点击(此处)折叠或打开
- #include "httpWindow.h"
-
- HttpWindow::HttpWindow()
- {
- urlLineEdit = new QLineEdit("http://");
- urlLabel = new QLabel(tr("&URL:"));
- urlLabel->setBuddy(urlLineEdit);
- statusLabel = new QLabel(tr("please input http addr"));
- downloadButton = new QPushButton(tr("download"));
- downloadButton->setDefault(true);
- progressDialog = new QProgressDialog(this);
- //构建QHttp类
- http = new QHttp(this);
- //绑定信号和槽函数
- connect(urlLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableDownload()));
- connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(requestFinishedSlot(int, bool)));
- connect(http, SIGNAL(dataReadProgress(int, int)), this, SLOT(dataReadProgressSlot(int, int)));
- connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)), this, SLOT(responseHeaderReceivedSlot(const QHttpResponseHeader&)));
- connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancleDownload()));
- connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
-
- QHBoxLayout *topLayout = new QHBoxLayout();
- topLayout->addWidget(urlLabel);
- topLayout->addWidget(urlLineEdit);
- topLayout->addWidget(downloadButton);
-
- QVBoxLayout *mainLayout = new QVBoxLayout();
- mainLayout->addLayout(topLayout);
- mainLayout->addWidget(statusLabel);
- setLayout(mainLayout);
- urlLineEdit->setFocus();
- }
- //如果输入框没有网址,那么就不能下载
- void HttpWindow::enableDownload()
- {
- downloadButton->setEnabled(!urlLineEdit->text().isEmpty());
- }
- //开始下载文件
- void HttpWindow::downloadFile()
- {
- //取得输入框的内容
- QUrl url(urlLineEdit->text());
- QFileInfo fileinfo(url.path());
- QString fileName = fileinfo.fileName();
- if(fileName.isEmpty())
- fileName = "index.html";
- //如果文件已经存在就提示用户是否覆盖
- if(QFile::exists(fileName))
- {
- if(QMessageBox::question(this, tr("HTTP"), tr("%1 is in,are you sure instead?").arg(fileName), QMessageBox::Yes, QMessageBox::No)==QMessageBox::No)
- return;
- QFile::remove(fileName);
- }
-
- file = new QFile(fileName);
- if(!file->open(QIODevice::WriteOnly))
- {
- QMessageBox::information(this, tr("12"),tr("23"));
- delete file;
- file = 0;
- return;
- }
- //选择链接类型https还是http
- QHttp::ConnectionMode mode = url.scheme().toLower()=="https" ? QHttp::ConnectionModeHttps:QHttp::ConnectionModeHttp;
- http->setHost(url.host(), mode, url.port()==-1?0:url.port());
- //设置用户名和密码
- if(url.userName().isEmpty())
- http->setUser(url.userName(), url.password());
- httpRequestAborted = false;
- QByteArray path = QUrl::toPercentEncoding(url.path(),"!$&'()*+,;=:@/");
- if(path.isEmpty())
- path = "/";
- //获取文件
- httpGetId = http->get(path, file);
-
- progressDialog->setWindowTitle("http");
- progressDialog->setLabelText("123");
- downloadButton->setEnabled(false);
- }
- //分析http服务器的应答码
- void HttpWindow::responseHeaderReceivedSlot(const QHttpResponseHeader &responseHeader)
- {
- switch(responseHeader.statusCode())
- {
- case 200:
- case 301:
- case 302:
- case 303:
- case 307:
- break;
- default:
- QMessageBox::information(this, tr("failed"), tr("hehe"));
- httpRequestAborted = true;
- progressDialog->hide();
- http->abort();
- }
- }
- //如果请求码不是要获取文件,那么就删除文件
- void HttpWindow::requestFinishedSlot(int requestId, bool error)
- {
- if(requestId!=httpGetId)
- return;
- if(httpRequestAborted)
- {
- if(file)
- {
- file->close();
- file->remove();
- delete file;
- file = 0;
- }
- progressDialog->hide();
- return;
- }
- progressDialog->hide();
- file->close();
- if(error)
- {
- file->remove();
- QMessageBox::information(this, tr("HTTP"), tr("down failed:%1").arg(http->errorString()));
- }
- else
- {
- QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
- statusLabel->setText(tr("down file here"));
- }
- downloadButton->setEnabled(true);
- delete file;
- file = 0;
- }
- //更新进度条
- void HttpWindow::dataReadProgressSlot(int byteRead, int totalByte)
- {
- if(httpRequestAborted)
- return;
- progressDialog->setMaximum(totalByte);
- progressDialog->setValue(byteRead);
- }
- //取消下载
- void HttpWindow::cancleDownload()
- {
- statusLabel->setText("cancle");
- httpRequestAborted = true;
- http->abort();
- downloadButton->setEnabled(true);
- }
二、socket
在LINUX下进行网络编程,我们可以使用LINUX提供的统一的套接字接口。但是这种方法牵涉到太多的结构体,比如IP地址,端口转换等,不熟练的人往往容易犯这样那样的错误。QT中提供的SOCKET完全使用了类的封装机制,使用户不需要接触底层的各种结构体操作
1、传输层协议
传输层协议主要有两种TCP和UDP
Tcp:面向连接的、可靠的、基于字节流的传输层控制协议。TCP可以为应用程序提供可靠的数据传输,从一端发出的数据可以毫无差错的传送到另一端。在传输数据之前双方必须建立连接,对于数据要求高的程序,可以使用TCP传输
Udp:提供无连接的不可靠的报文传输,一般可以用在以下场合:
1)、聊天软件
2)、流媒体数据
3)、视频聊天
2、TCP服务器
TC服务器建立的一般步骤:初始化、绑定、监听、接受连接、传输数据、关闭
1)、Qt提供了QTcpServer类,可以帮组我们建立服务器,这个类继承自 QOBJECT
QTcpServer server = new QTcpServer(this);
2)、使用listen方法来监听
server->listen(ip,port)
3)、nextPendingConnection建立连接,返回QTcpSocket
QTcpSocket socket = server->nextPendingConnection()
4)、写入数据write
socket->write();
点击(此处)折叠或打开
- #include "server.h"
-
- Server::Server()
- {
- //创建服务器
- tcpServer = new QTcpServer();
- //开始监听
- if(!tcpServer->listen(QHostAddress::Any, 6789))
- {
- tcpServer->close();
- return;
- }
- ipLabel = new QLabel(tr("服务器IP"));
- portLabel = new QLabel(tr("端口"));
- ipLineEdit = new QLineEdit();
- portLineEdit = new QLineEdit();
- receiveLabel = new QLabel(tr("接收数据"));
- sendLabel = new QLabel(tr("发送数据"));
- sendTextEdit = new QTextEdit();
- receiveTextEdit = new QTextEdit();
- sendButton = new QPushButton(tr("发送"));
- ipLabel->setText((QString)tcpServer->serverAddress());
- QHBoxLayout *hLay1 = new QHBoxLayout();
- hLay1->addWidget(ipLabel);
- hLay1->addWidget(ipLineEdit);
- hLay1->addWidget(portLabel);
- hLay1->addWidget(portLineEdit);
- QHBoxLayout *hLay2 = new QHBoxLayout();
- hLay2->addWidget(sendLabel);
- hLay2->addWidget(receiveLabel);
- QHBoxLayout *hLay3 = new QHBoxLayout();
- hLay3->addWidget(sendTextEdit);
- hLay3->addWidget(receiveTextEdit);
- QVBoxLayout *mainLay = new QVBoxLayout();
- mainLay->addLayout(hLay1);
- mainLay->addLayout(hLay2);
- mainLay->addLayout(hLay3);
- mainLay->addWidget(sendButton);
-
- connect(tcpServer, SIGNAL(newConnection()), this, SLOT(enableSend()));
- connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage()));
- setLayout(mainLay);
- setWindowTitle(tr("TCP服务器"));
- sendButton->setDisabled(true);
-
- }
-
- void Server::enableSend()
- {
- //建立链接
- qDebug()"new connection!!!";
- sendButton->setEnabled(true);
- socket = tcpServer->nextPendingConnection();
- }
- void Server::sendMessage()
- {
- //初始化数据
- QByteArray block;
- QDataStream out(&block, QIODevice::ReadWrite);
- out.device()->seek(0);
- outsendTextEdit->toPlainText();
-
- qDebug()"send";
- if(socket!=NULL)
- {
- connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
- socket->write(block);
- }
- if(socket==NULL)
- qDebug()"failed";
- }
3、TCP客户端
TCP客户端建立的一般步骤:初始化套接字、建立连接、数据传输、关闭
1)、创造套接字
QTcpSocket socket = new QTcpSocket();
2)、连接到服务器
socket->connectToHost(ip,port);
3)、传输数据
当有数据来的时候会发出readyRead信号
点击(此处)折叠或打开
- #include "client.h"
-
- Client::Client()
- {
- QVBoxLayout *vLay = new QVBoxLayout();
- text = new QTextEdit();
- vLay->addWidget(text);
- setLayout(vLay);
- socket = new QTcpSocket();
- connect(socket, SIGNAL(readyRead()), SLOT(readMessage()));
- connect(socket, SIGNAL(disconnected()), SLOT(disSlot()));
- socket->connectToHost("LocalHost", 6789);
- }
-
- void Client::readMessage()
- {
- QDataStream in(socket);
- QString m;
- in>>m;
- qDebug()m;
- }
- void Client::disSlot()
- {
- qDebug()"disconnect";
- }
点击(此处)折叠或打开
- #include "client.h"
-
- Client::Client()
- {
- QVBoxLayout *vLay = new QVBoxLayout();
- text = new QTextEdit();
- vLay->addWidget(text);
- setLayout(vLay);
- socket = new QTcpSocket();
- connect(socket, SIGNAL(readyRead()), SLOT(readMessage()));
- connect(socket, SIGNAL(disconnected()), SLOT(disSlot()));
- socket->connectToHost("LocalHost", 6789);
- }
-
- void Client::readMessage()
- {
- QDataStream in(socket);
- QString m