一、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、实例
-
#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);
-
out<<sendTextEdit->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
阅读(3292) | 评论(0) | 转发(0) |