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 ...
随机推荐
- Luogu P3007 奶牛议会
观前须知 本题解使用 CC BY-NC-SA 4.0 许可. 同步发布于 Luogu 题解区. 更好的观看体验 请点这里. 笔者的博客主页 正文 Luogu P3007 [USACO11JAN] Th ...
- CTFshow Reverse 逆向4 学习记录
题目 分析过程 是一个无壳,64位的文件 丢到IDA里面,找到main函数 1 int __cdecl __noreturn main(int argc, const char **argv, con ...
- mysql 必知必会整理—sql 排序与过滤[三]
前言 简单整理一下MySQL的排序与过滤. 正文 我们查询出来的结果有时候是希望进行排序的,比如说: select product_name from products order by prod_n ...
- mysql 必知必会整理——mysql 介绍[一]
前言 对mysql 进行简介. 正文 mysql 是一种数据库,那么什么是数据库呢? 数据库是一个以某种有组织的方式存储的数据集合. 也就是说数据有某种组织规律的就叫做数据库. 数据库(databas ...
- 力扣636(java)-函数的独占时间(中等)
题目: 有一个 单线程 CPU 正在运行一个含有 n 道函数的程序.每道函数都有一个位于 0 和 n-1 之间的唯一标识符. 函数调用 存储在一个 调用栈 上 :当一个函数调用开始时,它的标识符将会 ...
- 力扣150(java)-逆波兰表达式求值(中等)
题目: 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. 可以保证给定的逆波兰表达式 ...
- EasyNLP集成K-BERT算法,借助知识图谱实现更优Finetune
导读 知识图谱(Knowledge Graph)的概念⾸次出现2012年,由Google提出,它作为⼀种⼤规模语义⽹络, 准确地描述了实体以及实体之间的关系.知识图谱最早应⽤于搜索引擎,⽤于准备返回⽤ ...
- 服务网格 ASM 年终总结:最终用户如何使用服务网格?
简介:本文不打算回顾 Istio 或是阿里云服务网格 ASM 的变化或趋势,我们来聊一聊阿里云 ASM 服务网格,它的最终用户是如何使用服务网格的. 作者:叶剑宏 背景 阿里云服务网格 ASM 于 ...
- 双11特刊|购物车实时显示到手价,看云原生内存数据库Tair如何提升用户体验?
阿里云自研内存数据库Tair诞生于2009年,是一种支持高并发低延迟访问的云原生内存数据库,完全兼容Redis,已历经多年双11大促考验,提供核心在线访问加速能力,显著提升系统吞吐量. 作为双11大 ...
- Inclavare Containers:云原生机密计算的未来
简介:本文为你详细的梳理一次 Inclavare Containers 项目的发展脉络,解读它的核心思想和创新技术. 作为业界首个面向机密计算场景的开源容器运行时,Inclavare Conta ...