前言
本实验因为时间有限,写的比较草率。。。
白嫖容易,创作不易,本文原创,转载请注明!!!
源码和可运行程序:
链接:https://pan.baidu.com/s/1A9KctmpP2JJgyW2wLrehIg
提取码:Lin2
计算机网络课程设计:
计算机网络课程设计之网络聊天程序的设计与实现
计算机网络课程设计之Tracert与Ping程序设计与实现
计算机网络课程设计之基于 IP 多播的网络会议程序
计算机网络课程设计之网络嗅探器的设计与实现
计算机网络课程设计之电子邮件客户端程序设计与实现
计算机网络课程设计之TELNET 终端设计与实现
计算机网络课程设计之网络代理服务器的设计与实现
计算机网络课程设计之简单 Web Server 程序的设计与实现
Qt入门系列:
Qt学习之C++基础
Qt学习之Qt安装
Qt学习之Qt基础入门(上)
Qt学习之Qt基础入门(中)
Qt学习之Qt基础入门(下)
创作不易,整个课程设计程序3000多行代码,所有实验都写在了一个程序中,时间有限,能力不足,转载望注明!!!
本文链接
个人博客:https://ronglin.fun/archives/276
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/122510609
实验题目
网络代理服务器的设计与实现
实验目的
实现一个简易的 proxy 程序。proxy 程序的功能:能够做“二传手”的工作。它自身处在能同时连通外界目标服务器和我的机器的位置上。我的机器把请求发送给它,它接受请求,把请求原封不动的抄下来发送给外界目标服务器;外界目标服务器响应了请求,把回答发送给它,它再接受回答,把回答原封不动的抄下来发送给我的机器。这样,我的机器实际上是把它当作了目标服务器(由于是原封不动的转抄,请求和回答没有被修改)。而它则是外界目标服务器的客户端。
总体设计
(含背景知识或基本原理与算法、或模块介绍、设计步骤等)
一共想了三种实现方法
第一种:
这种最简单,这个Proxy的设计思路为写一个proxy客户端和一个proxy服务器,客户端和服务器用TCP连接,然后客户端将要请求的网站发给服务器,然后服务器发出一个HTTP/HTTPS请求,然后将请求的返回数据再通过TCP把数据发送给proxy客户端。这种思路有一个问题就是当关闭代理的时候,proxy客户端是没有办法发出请求的
第二种:
这种思路是在思路一的基础上,给客户端增加一个判断,如果连接了proxy服务器的时候,就把网站发送给proxy服务器,如果没有连接proxy服务器的话,就自己发出一个HTTP/HTTPS请求,然后处理接受的数据,这种是最符合proxy代理的展示作用的
第三种:
这种思路是前两者的增强版,因为前两者只是用来展示作用,实际上是没啥实际作用的,我想的第三种思路是,当启动proxy服务器的时候,监听客户端发出的所有请求,作为一个中介,然后拦截下来,分析请求头,然后重新构造一个请求发出,然后把返回结果通过TCP返还给proxy客户端
详细设计
(含主要的数据结构、程序流程图、关键代码等)
时间有限,决定用第一种思路
难点主要在于Qt发出一个HTTP/HTTPS请求,HTTP简单,但是HTTPS比较麻烦,下面说明一下Qt如何发出一个HTTP/HTTPS请求
参考博客:
https://blog.csdn.net/gongjianbo1992/article/details/97568863
//构建一个manager对象
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//manager具有异步API,当http请求完成后,会通过finished信号进行通知
connect(manager,&QNetworkAccessManager::finished,this,&MyClass::replyFinished);
//发送异步get请求
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
当完成请求的接收数据的时候,会触发槽函数,然后就可以处理数据,处理数据如下:
//connect(manager,&QNetworkAccessManager::finished,this,&MyClass::replyFinished);
//槽函数
void MyClass::replyFinished(QNetworkReply *reply)
{
if(reply->error()!=QNetworkReply::NoError){
//处理中的错误信息
qDebug()<<"reply error:"<<reply->errorString();
}else{
//请求方式
qDebug()<<"operation:"<<reply->operation();
//状态码
qDebug()<<"status code:"<<reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug()<<"url:"<<reply->url();
//qDebug()<<"raw header:"<<reply->rawHeaderList();
//获取响应信息
const QByteArray reply_data=reply->readAll();
qDebug()<<"read all:"<<reply_data;
}
reply->deleteLater();
}
然后完成了一次HTTP请求
对于HTTPS的请求
首先要先获取需要的OpenSSL版本
bool bSupp = QSslSocket::supportsSsl();
QString buildVersion = QSslSocket::sslLibraryBuildVersionString();
QString version = QSslSocket::sslLibraryVersionString();
// true "OpenSSL 1.0.2j 26 Sep 2016" "OpenSSL 1.0.2f 28 Jan 2016"
// qDebug() << bSupp << buildVersion << version << endl;
我这里输出
true "OpenSSL 1.0.2j 26 Sep 2016" "OpenSSL 1.0.2f 28 Jan 2016"
说明需要的是OpenSSL 1.0.2j
的版本,然后去搜索,下载好两个文件放在exe同级文件夹下即可
// 发送https请求前准备工作;
QSslConfiguration config;
QSslConfiguration conf = request.sslConfiguration();
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
conf.setProtocol(QSsl::AnyProtocol);
request.setSslConfiguration(conf);
request.setUrl(QUrl(URL));
manager->get(request);
然后配置好即可
实验结果与分析
界面如下
先启动proxy服务器,然后登录,然后点击请求
然后请求成功,发现请求的百度的数据已经返回回来了。
小结与心得体会
时间仓促,没有写的很好,只是为了实现演示而设计功能,不过对于proxy有了了解。
=w=