Http 代理工具 实战 支持网页与QQ代理
前言:
有些公司不让员工上Q或封掉某些网站,这时候,干着急没办法,只能鄱墙。如果上网搜代理IP,很少能用,用HTTP-Tunnel Client代理软件,免费的也是经常性的掉线。正好手头上有N台服务器,如果直接在上面装个CCProxy,也显的太明显了。于是自己写个代理软件放上去,一来包装一下好伪装,二来又有代理功能,看着挺好。
原理解说:
1:创建一个Socket进行本地端口监听-》一个死循环while语句2:收到消息时,产生一个线程处理->多线程处理并发请求3:产生一个新的Socket负责转发和接收4:原来的Socket负责把新接收的消息发送回客户端
代码细说
说明:本次示例在控制台程序里运行。
一:Program.cs
1:简单函数原型
using System;using System.Collections.Generic;using System.Text;using System.Diagnostics;using System.Net.Sockets;using System.Threading;namespace TcpProxy{ /// <summary> /// by 路过秋天 /// http://www.cnblogs.com/cyq1162 /// </summary> class Program { static void Main(string[] args) { Listen(808);//起始监听808和CCProxy一样。 } static void Write(string msg)//简化消息输出 { Console.WriteLine(msg); } static void Listen(int port)//开始监听 { } static void ReListen(TcpListener listener)//监听失败,需要重新换端口监听 { } }}
2:开始监听
static void Listen(int port)//开始监听 { Write("准备监听端口:" + port); System.Net.IPAddress ipp = System.Net.IPAddress.Parse("0.0.0.0");//监听本地任意IP TcpListener tcplistener = new TcpListener(ipp, port); //端口复用,xp下可以复用[可抢占IIS80端口],win2003下无效。 tcplistener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); try { tcplistener.Start(); } catch (Exception err) { Write(err.Message); Write("该端口已被占用,请更换端口号!!!"); ReListen(tcplistener);//监听失败,切换端口监听 } //下面还有代码,暂时省略 }
3:监听失败,切换端口监听
static void ReListen(TcpListener listener)//监听失败,需要重新换端口监听 { if (listener != null) { listener.Stop(); listener = null; } Write("请输入监听端口号:"); string newPort = Console.ReadLine(); int port; if (int.TryParse(newPort, out port)) { Listen(port); } else { ReListen(listener); } }
4:开始监听,进入死循环
static void Listen(int port)//开始监听 { //上面代码省略...... Write("成功监听端口:" + port); Socket socket; while (true) { socket = tcplistener.AcceptSocket();//获取传送和接收数据的Scoket实例 Proxy proxy = new Proxy(socket);//Proxy类实例化 Thread thread = new Thread(new ThreadStart(proxy.Run));//创建线程 thread.Start();//启动线程 } }
作者:路过秋天
博客:http://cyq1162.cnblogs.com/
二:Proxy.cs
Proxy简单函数原型:
using System;using System.Collections.Generic;using System.Text;using System.Net;using System.Net.Sockets;using System.IO;namespace TcpProxy{ /// <summary> /// by 路过秋天 /// http://www.cnblogs.com/cyq1162 /// </summary> public class Proxy { Socket clientSocket;//接收和返回 byte[] read = null;//存储来自客户端请求数据包 byte[] sendBytes = null;//存储中转请求发送的数据 byte[] recvBytes = null;//存储中转请求返回的数据 bool isConnect = false; byte[] qqSendBytes=new byte[4096];//QQ发送缓冲 byte[] qqRecvBytes = new byte[4096];//QQ接收缓冲 int sendLength = 0, recvLength = 0;//实际发送和接收长度 public Proxy(Socket socket)//初始化 { clientSocket = socket; recvBytes = new Byte[1024 * 1024]; clientSocket.ReceiveBufferSize = recvBytes.Length; clientSocket.SendBufferSize = recvBytes.Length; } public void Run(){}//主运行代码 //从请求头里解析出url和端口号 private string GetUrl(string clientmessage, ref int port){} //接收客户端的HTTP请求数据 private int ReadMessage(byte[] readByte, ref Socket s, ref IPAddress ipAddress, ref string host, ref int port){} //关闭socket private void CloseSocket(Socket socket){} private void CloseSocket(Socket socket, bool shutdown){} //QQ代理测试返回 private byte[] QQokProxyData(){} //firfox默认会发送一些请求,很烦,所以加过滤 private bool Filter(string url){ } private void Write(string msg) { System.Console.WriteLine(msg); } }}
Run主函数
A:分解请求头,获取要请求的IP,端口
#region 获取客户端请求数据 Write("-----------------------------请求开始---------------------------"); read = new byte[clientSocket.Available]; IPAddress ipAddress = IPAddress.Any; string host = "";//主机 int port = 80;//端口 int bytes = ReadMessage(read, ref clientSocket, ref ipAddress, ref host, ref port); if (bytes == 0) { Write("读取不到数据!"); CloseSocket(clientSocket); return; } #endregion
Run函数分解:ReadMessage函数
//接收客户端的HTTP请求数据 private int ReadMessage(byte[] readByte, ref Socket s, ref IPAddress ipAddress, ref string host, ref int port) { try { int bytes = s.Receive(readByte, readByte.Length, 0); Write("收到原始请求数据:" + readByte.Length); string header = Encoding.ASCII.GetString(readByte); host = GetUrl(header, ref port); if (Filter(host)) { Write("系统过滤:" + host); return 0; } Write(header); ipAddress = Dns.GetHostAddresses(host)[0]; if (!isConnect) { header = header.Replace("http://" + host, ""); } sendBytes = Encoding.ASCII.GetBytes(header); System.Threading.Thread.Sleep(50); Write("转发请求数据:" + sendBytes.Length); Write(Encoding.ASCII.GetString(sendBytes)); return bytes; } catch { System.Threading.Thread.Sleep(300); return 0; } }
ReadMessage函数分解:GetUrl
//从请求头里解析出url和端口号 private string GetUrl(string clientmessage, ref int port) { if (clientmessage.IndexOf("CONNECT") != -1) { isConnect = true; } int index1 = clientmessage.IndexOf(' '); int index2 = clientmessage.IndexOf(' ', index1 + 1); if ((index1 == -1) || (index2 == -1)) { return ""; } string part1 = clientmessage.Substring(index1 + 1, index2 - index1).Trim(); string url = string.Empty; if (!part1.Contains("http://")) { if (part1.Substring(0, 1) == "/") { part1 = "127.0.0.1" + part1; } part1 = "http://" + part1; } Uri uri = null; try { uri = new Uri(part1); } catch { return ""; } url = uri.Host; port = uri.Port; return url; }
ReadMessage函数分解:Filter
Filter函数
private bool Filter(string url) { switch (url.ToLower()) { case "fffocus.cn": return true; } return false; }
Run函数分解:CloseSocket函数
private void CloseSocket(Socket socket) { CloseSocket(socket, true); } private void CloseSocket(Socket socket, bool shutdown) { if (socket != null) { if (shutdown) { socket.Shutdown(SocketShutdown.Both); } socket.Close(); } }
B:创建中转Socket及建立连接
#region 创建中转Socket及建立连接 IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, port); Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { IPsocket.Connect(ipEndpoint); Write("-----Socket 建立连接! IP地址:" + ipAddress + "网址:http://" + host); } catch (Exception err) { Write("连接失败 :" + err.Message); Write("退出请求!!!"); CloseSocket(IPsocket, false); return; } #endregion
C:QQ代理测试及网页转发
if (isConnect)//QQ链接方式 { byte[] qqOkData = QQokProxyData(); clientSocket.Send(qqOkData, 0, qqOkData.Length, 0); } else//正常网页,直接转发 { IPsocket.Send(sendBytes, 0); }
函数分解:QQokProxyData
private byte[] QQokProxyData() { string data = "HTTP/1.0 200 Connection established";//返回建立成功"; return System.Text.Encoding.ASCII.GetBytes(data); }
D:针对QQ需要进行重复来回的发送与接收
#region QQ发送/接收中转请求 int length = 0, count = 0; if (isConnect) { System.Threading.Thread.Sleep(400);//关键时延 //循环发送客户端请求,接收服务器返回 DateTime start = DateTime.Now; while (true) { if (IPsocket.Available == 0 && clientSocket.Available == 0) { if (((TimeSpan)(DateTime.Now - start)).TotalMinutes > 15) { break;//掉线重拔处理 } } else { start = DateTime.Now; } try { while (clientSocket.Available != 0) { sendLength = clientSocket.Receive(qqSendBytes, qqSendBytes.Length, 0); IPsocket.Send(qqSendBytes, sendLength, 0); Write("发送字节数: " + sendLength.ToString()); } System.Threading.Thread.Sleep(500); while (IPsocket.Available != 0) { recvLength = IPsocket.Receive(qqRecvBytes, qqRecvBytes.Length, 0); clientSocket.Send(qqRecvBytes, recvLength, 0); Write("接收字节数: " + recvLength.ToString()); } } catch { } } } else { try { do { length = IPsocket.Receive(recvBytes, count, IPsocket.Available, 0); count = count + length; Write("接收转发请求返回的数据中..." + length); System.Threading.Thread.Sleep(200);//关键点,请求太快数据接收不全 } while (IPsocket.Available > 0); clientSocket.Send(recvBytes, 0, count, 0); } catch(Exception err) { Write(err.Message); } } #endregion
E:结束请求,关闭客户端Socket
#region 结束请求,关闭客户端Socket Write("接收完成。返回客户端数据..." + count); CloseSocket(IPsocket); CloseSocket(clientSocket); recvBytes = null; Write("本次请求完成,已关闭连接..."); Write("-----------------------------请求结束---------------------------"); #endregion
结言:
本QQ代理软件在服务器上运行长达三个多月,使用过程未发现异常退出情况。当然前提就我一个人在用了~哈哈~
附以前写的几篇文章:
Http 代理工具 实战 支持网页与QQ代理的更多相关文章
- 跨平台web调试代理工具---whistle
whistle是基于Node实现的跨平台web调试代理工具,支持windows.mac.linux等所有安装了Node的操作系统,可以部署在本地机器.虚拟机或远程服务器,并通过本地网页查看或修改HTT ...
- 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫
前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,本文记录免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作 ...
- 内网代理工具--reGeorg
一.简介 reGeorg是reDuh的继承者,利用了会话层的socks5协议,效率更高结合Proxifier使用 Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工 ...
- 【转】fiddler-http协议调试代理工具
题目有一些激进.但是在前端界打滚了这么多年,fiddler一直都是陪着我走过来了.它就是一个抓包神奇,代理神器.它的厉害之处,我简单地说一下,希望你们看了以后,能点上32个赞. 1.fiddler为何 ...
- Atitit 项目管理(5)----------后勤管理与工具链支持管理
Atitit 项目管理(5)----------后勤管理与工具链支持管理 1.1. keyword1 1.2. 15个辅助软件1 1.3. 公共模块管理(100个即可)2 1.4. 第三方类库表2 1 ...
- 爬虫 Http请求,urllib2获取数据,第三方库requests获取数据,BeautifulSoup处理数据,使用Chrome浏览器开发者工具显示检查网页源代码,json模块的dumps,loads,dump,load方法介绍
爬虫 Http请求,urllib2获取数据,第三方库requests获取数据,BeautifulSoup处理数据,使用Chrome浏览器开发者工具显示检查网页源代码,json模块的dumps,load ...
- 代理工具Charles使用
代理工具Charles使用 分类: MAC 2014-03-27 20:41 7810人阅读 评论(2) 收藏 举报 手机开发 一.跟踪HTTPS 1.下载官方的证书ssl.zip证书,解压成*.cr ...
- 性能测试专题:Locust工具实战之“蝗虫”降世
阅读全文需5分钟. 1. 前言 在上一篇文章中,我们已经为大家介绍了什么是Locust,具体可参照:性能专题:Locust工具实战之开篇哲学三问,简单来说,Locust 是基于 Python 语言下的 ...
- http代理工具delphi源码
http://www.caihongnet.com/content/xingyexinwen/2013/0721/730.html http代理工具delphi源码 以下代码在 DELPHI7+IND ...
- web调试代理工具Whistle
由于最近在学习微信小程序开发,项目中用到了https代理请求,所以用到了基于Node实现的跨平台web调试代理工具Whistle,在此做一记录. 完成https代理请求总共需要5个步骤. 一.安装No ...
随机推荐
- 浅谈TypeScript对业务可维护性的影响
前言 笔者认为, TypeScript是服务于业务的, 核心就是提高代码的可维护性. TypeScript是把双刃剑, 如果类型系统使用的不好, 反而会阻碍开发, 甚至最后就变成了anyScript. ...
- 如何用一行 CSS 实现 10 种现代布局
现代 CSS 布局使开发人员只需按几下键就可以编写十分有意义且强大的样式规则.上面的讨论和接下来的帖文研究了 10 种强大的 CSS 布局,它们实现了一些非凡的工作. 01. 超级居中:place-i ...
- textfsm 案例分享
由于安全需要,需要定期对接入层交换机配置进行合规检查,避免不规范配置存在的漏洞给公司网络带来安全风险. 如下案例是通过textfsm 提取交换机接口的配置信息,进一步进行检查准入配置是否开启: 1.首 ...
- 【git】ignore文件详解
1.功能 可以指定git,对于某些文件或者文件夹不进行追踪记录,例如一些依赖或者编译中间文件等. 2.使用注意 2.1 对于已经有提交记录的文件 对于已经提交的文件,即使加入了ignore文件也会被g ...
- Oracle 将字符中含有的字母或特殊字符去除并将字符串置换成数字
将字符中含有的字母或特殊字符去除并将字符串置换成数字 将字符中含有的字母或特殊字符去除并将字符串置换成数字 to_number(nvl(TRANSLATE(u.scsqrbzl, 'qwertyuio ...
- 技术门槛高?来看 Intel 机密计算技术在龙蜥社区的实践 | 龙蜥技术
简介: 数据可用不可见是怎么做到的? 编者按:龙蜥社区云原生机密计算 SIG 定位于云原生机密计算底层基础设施,专注于机密计算底层技术.在阿里巴巴开源开放周中, 龙蜥社区机密计算 SIG Mainta ...
- 使用Databricks+Mlflow进行机器学习模型的训练和部署【Databricks 数据洞察公开课】
简介: 介绍如何使用Databricks和MLflow搭建机器学习生命周期管理平台,实现从数据准备.模型训练.参数和性能指标追踪.以及模型部署的全流程. 作者:李锦桂 阿里云开源大数据平台开发工程 ...
- 外部工具连接SaaS模式云数据仓库MaxCompute实战——商业BI分析工具篇
简介: MaxCompute 是面向分析的企业级 SaaS 模式云数据仓库,以 Serverless 架构提供快速.全托管的在线数据仓库服务,消除了传统数据平台在资源扩展性和弹性方面的限制,最小化用户 ...
- [Gse] 高效的Golang中文分析库推荐
优点:用法简单,支持各种语言,基本满足需求. 缺点:默认分词字典文件有 8M 需测试使用速度. 我们可以直接封装一个简单的辅助方法来实现分词功能: // @author cnblogs.com/far ...
- dotnet SemanticKernel 入门 开篇
本文将开坑告诉大家什么是 SemanticKernel 以及如何使用框架 众所周知 GPT 是一个大语言模型,能够参与的输入和输出是文本内容.而想要让 GPT 完成各项功能,则需要对接现有的编程世界. ...