首页 > 其他分享 >Http 代理工具 实战 支持网页与QQ代理

Http 代理工具 实战 支持网页与QQ代理

时间:2024-05-27 21:55:08浏览次数:30  
标签:QQ Http Socket int 代理 System Write port string

前言:

有些公司不让员工上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代理软件在服务器上运行长达三个多月,使用过程未发现异常退出情况。当然前提就我一个人在用了~哈哈~

 

 

附以前写的几篇文章:

1:简单实现Http代理工具

2:简单实现Http代理工具--端口复用与QQ代理

3:简单实现Http代理工具--完善支持QQ代理

4:C# 控制台程序 不显示在任务栏 只在进程中显示

 

 https://www.cnblogs.com/cyq1162/archive/2010/09/21/1832329.html

标签:QQ,Http,Socket,int,代理,System,Write,port,string
From: https://www.cnblogs.com/webenh/p/18216629

相关文章

  • Nginx R31 doc-13-Limiting Access to Proxied HTTP Resources 访问限流
    前言大家好,我是老马。很高兴遇到你。我们为java开发者实现了java版本的nginxhttps://github.com/houbb/nginx4j如果你想知道servlet如何处理的,可以参考我的另一个项目:手写从零实现简易版tomcatminicat手写nginx系列如果你对netty不是很熟悉,可以读一下从......
  • c++设计模式-装饰器模式和代理模式
    namespace_nmsp1{//抽象的控件类classControl{public:virtualvoiddraw()=0;//draw方法,用于将自身绘制到屏幕上。public:virtual~Control(){}//做父类时析构函数应该为虚函数};//列表控件类classListCtrl......
  • nginx开启ssl并把http重定向到https
    前言Nginx是一个非常强大和流行的高性能Web服务器。本文讲解Nginx如何整合https并将http重定向到https。Nginx的特点(1)热启动:例如当修改配置文件后,不需要停止与启动就可以让配置生效,命令:nginx-sreload(2)高并发连接:顶住10万以上连接是没有问题的。(3)低内存消耗:在高性能的同时......
  • 通过adb设置雷电模拟器的HTTP代理
    连接雷电模拟器.\adbconnect127.0.0.1:5555获取路由地址,一般为172.16.1.2(这里我的笔记本显示是172.16.1.1,但是未设置成功,那就用172.16.1.2).\adb-s127.0.0.1:5555shell'iproutelisttableallscopeglobal|cut-F3'.\adb-s127.0.0.1:5555shellsettingsputgl......
  • 如何使用ADB shell设置Android设备的全局HTTP代理
    打开ADB调试这里使用蓝叠模拟器进行测试下载adbhttps://dl.google.com/android/repository/platform-tools-latest-windows.zip解压好,放哪都行在platform-tools目录下,右击空白处,选择“在终端中打开”开始操作建立连接.\adbconnectlocalhost:5555启动shell会话......
  • 接口报错.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework
    1、报文:.w.s.m.s.DefaultHandlerExceptionResolver:Resolved[org.springframework.http.converter.HttpMessageNotReadableException:JSONparseerror:Unexpectedcharacter('''(code39)):wasexpectingdouble-quotetostartfieldname;nestedex......
  • 克里金代理模型Kriging
    Kriging笔记_代理模型由于Kriging模型不仅能对未知点的适应值进行预测,还能对其预测的不确定性进行估计。因此,其被广泛应用于代理模型辅助进化算法中,以解决昂贵单目标或多目标优化问题。使用下面的公式来估计未知点x的适应值:(均值+正态分布求解适应度值)......
  • Edge浏览器http自动跳转https
        今天上午遇到了一个很纳闷的事情,就是说原本是http网址,复制到Edge浏览器里它会自动修改为https网址,这样http网址就无法加载进去(起初我think是网址本身的问题,换了多个浏览器都是以失败告终,后面我发现用手机浏览器登陆这个http网址是没有问题的,经过仔细勘察,发现问题所......
  • springmvc 前端向后端发送http请求报错“HTTP状态 405 - 方法不允许”
    如图我使用前端向后端发送文件时报错,405方法不允许,于是我就检查了前后端的method方法设置是否一致?  检查后发现明明前后端请求方式一致,都是post遵循文件上传的方式。这个问题令我十分苦恼,最后发现原来是前端提交form表单时设置的选项之间存在逗号,原则是每一项之间都不应......
  • .NET集成DeveloperSharp实现http网络请求&与其它工具的比较
     爆了,爆了,DeveloperSharp系列近期又被制造业ERP、民航飞行App、建筑BIM、电力掌上营业厅、等多家大型采用,站在巨人的肩膀上你能走的更远。 支持.NetCore2.0及以上,支持.NetFramework4.0及以上http请求调用是开发中经常会用到的功能。在内,调用自有项目的WebApi等形式接口时......