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 ...
随机推荐
- HarmonyOS—UI 开发性能提升的推荐方法
注:本文转载自 HarmonyOS 官网文档 开发者若使用低性能的代码实现功能场景可能不会影响应用的正常运行,但却会对应用的性能造成负面影响.本章节列举出了一些可提升性能的场景供开发者参考,以避免应用 ...
- 全局模型可解释之部分依赖图:Partial Dependence Plot
本部分是来自大纲 模型可解释的一个子分支. 部分依赖图可以表示1个或者2个特征对模型的预测结果所能产生的边际效应.同时也能展示1个特征和label直接是否具有:线性相关性.单调性等. 当我们把pdp应 ...
- Java面试题:请谈谈对ThreadLocal的理解?
ThreadLocal是一种特殊的变量存储机制,它提供了一种方式,可以在每个线程中保存数据,而不会受到其他线程的影响.这种机制在多线程编程中非常有用,因为它允许每个线程拥有自己的数据副本,从而避免了数 ...
- axiso封装
import axios from 'axios';import {Message } from 'element-ui'//element-ui提示框组件import config from './ ...
- 【笔记】rocketMQ了解
记录rocketMQ 忘了从哪儿保存的图了 原图链接:https://www.jianshu.com/p/2838890f3284
- 力扣23(java)-合并k个升序链表(困难)
题目: 给你一个链表数组,每个链表都已经按升序排列. 请你将所有链表合并到一个升序链表中,返回合并后的链表. 示例 1: 输入:lists = [[1,4,5],[1,3,4],[2,6]]输出:[1 ...
- 数百万台车联网设备同时在线0故障,中瑞集团的云原生探索之路 | 云原生Talk
简介: 在保持对业界趋势调度关注的同时,始终选用最适合自身的技术,这可能是中瑞能在车联网领域引领行业的重要原因之一,正如中瑞CTO所说"阿里云云原生产品体系带给我们的,不是单纯的IT工具,而 ...
- GtkSharp 设置窗口背景透明
本文告诉大家如何在 GTK Sharp 里面设置窗口背景透明 在 GTK 里面设置窗口背景透明十分简单,只需使用如下代码即可 this.AppPaintable = true; var screen ...
- IIncrementalGenerator 判断程序集之间可见关系
本文告诉大家如何在使用 IIncrementalGenerator 进行增量的 Source Generator 生成代码时,如何判断两个程序集之间是否存在 InternalsVisibleTo 关系 ...
- dotnet 6 创建进程 Process.Start 时设置 UseShellExecute 在 Windows 下对性能的影响
本文将告诉大家,在 dotnet 6 或 dotnet 7 版本里,启动新的进程时,在 StartInfo 设置 UseShellExecute 为 true 和 false 时,对性能的影响 在 d ...