• 简单实现Http代理工具


    本来意图是想写个工具放到服务器里代理一下上秋秋的。

    没想到N台(电信/联通/移动)的服务器都把端口全封了。

    所以以下代码是在本地测试代理网页访问通过。

    说下思路再上代码及下载:

    其实一句话就是:产生两个Soket,一个负责接收请求和回发请求,另一个负责中转的去请求和接收。

    重点一句话就是:每个请求产生一个线程处理,处理时关键是的延时处理(不然数据接收不全)。

    现在上代码,Proxy自定义类:

    Proxy
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    //by 路过秋天
    namespace TCPProxy
    {
        
    public class Proxy
        {
            Socket clientSocket;
    //接收和返回
            Byte[] read = null;//存储来自客户端请求数据包
            Byte[] recvBytes = null;//存储中转请求返回的数据

            
    public Proxy(Socket socket)
            {
                clientSocket 
    = socket;
                recvBytes 
    = new Byte[1024 * 1024];
                clientSocket.ReceiveBufferSize 
    = recvBytes.Length;
                clientSocket.SendBufferSize 
    = recvBytes.Length;
                clientSocket.SendTimeout 
    = 10000;
                clientSocket.ReceiveTimeout 
    = 10000;
            }
            
    public void Run()
            {
                
    #region 获取客户端请求数据
                
    string clientmessage = "";
                read 
    = new byte[clientSocket.Available];
                
    int bytes = ReadMessage(read, ref clientSocket, ref clientmessage);
                
    if (bytes == 0)
                {
                    Write(
    "读取不到数据!");
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    
    return;
                }
                
    int port = 80;
                
    string url = GetUrl(clientmessage, port);
                
    #endregion
                
                
    try
                {
                    
    #region IP解析获取
                    IPHostEntry IPHost
    = Dns.GetHostEntry(url);
                    Write(
    "-----------------------------请求开始---------------------------");
                    Write(
    "http://" + IPHost.HostName);
                    
    string[] aliases = IPHost.Aliases;
                    IPAddress[] address 
    = IPHost.AddressList;//解析出要访问的服务器地址
                    Write("IP地址:" + address[0]);
                    
    #endregion
                   

                    
    #region 创建中转Socket及建立连接
                    IPEndPoint ipEndpoint 
    = new IPEndPoint(address[0], port);
                    Socket IPsocket 
    = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    
    //创建连接Web服务器端的Socket对象
                    IPsocket.Connect(ipEndpoint);
                    
    //Socket连Web接服务器
                    if (IPsocket.Connected)
                    {
                        Write(
    "Socket 正确连接!");
                    }
                    
    #endregion
                    
    #region 发送中转请求
                    IPsocket.Send(read, 
    0);
                    Write(
    "发送字节:" + read.Length);
                    
    #endregion
                    
    #region 接收中转请求数据
                    
    int length = 0, count = 0;
                    
    do
                    {
                        length 
    = IPsocket.Receive(recvBytes, count, IPsocket.Available, 0);
                        count 
    = count + length;
                        Write(
    "正在接收数据..." + length);
                        System.Threading.Thread.Sleep(
    100);//关键点,请求太快数据接收不全
                    }
                    
    while (IPsocket.Available > 0);
                    
    #endregion
                    
    #region 关闭中转请求Socket
                    IPsocket.Shutdown(SocketShutdown.Both);
                    IPsocket.Close();
                    
    #endregion

                    
    #region 将中转请求收到的数据发回客户端
                    clientSocket.Send(recvBytes, 
    0, count, 0);
                    Write(
    "正在返回数据..." + count);
                    
    #endregion
                    
    #region 结束请求,关闭客户端Socket
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    recvBytes 
    = null;
                    Write(
    "完成,已关闭连接...");
                    Write(
    "-----------------------------请求结束---------------------------");
                    
    #endregion
                }
                
    catch (Exception err)
                {
                    System.Console.WriteLine(err.Message 
    + err.Source);
                }

            }
            
    //从请求头里解析出url和端口号
            private string GetUrl(string clientmessage, int port)
            {
                
    int index1 = clientmessage.IndexOf(' ');
                
    int index2 = clientmessage.IndexOf(' ', index1 + 1);
                
    if ((index1 == -1|| (index2 == -1))
                {
                    
    throw new IOException();
                }
                
    string part1 = clientmessage.Substring(index1 + 1, index2 - index1).Trim();

                
    string url = string.Empty;
                
    if (!part1.Contains("http://"))
                {
                    part1 
    = "http://" + part1;
                }
                Uri uri 
    = new Uri(part1);
                url 
    = uri.Host;
                port 
    = uri.Port;
                
    return url;
            }
            
    //接收客户端的HTTP请求数据
            private int ReadMessage(byte[] readByte, ref Socket s, ref string clientmessage)
            {
                
    int bytes = s.Receive(readByte, readByte.Length, 0);
                clientmessage 
    = Encoding.ASCII.GetString(readByte);
                
    return bytes;
            }

            
    private void Write(string msg)
            {
                
    // return;
                System.Console.WriteLine(msg);
            }
        }
    }

    在控制台里调用:

    代码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.Net.Sockets;
    using System.Threading;
    namespace TCPProxy
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                    Listen(
    8989);
            }
            
    static void Write(string msg)
            {
                Console.WriteLine(msg);
            }

            
    static void Listen(int port)
            {
                Write(
    "准备监听端口:" + port);
                TcpListener tcplistener 
    = new TcpListener(port);
                
    try
                {
                    tcplistener.Start();
                }
                
    catch
                {
                    Write(
    "该端口已被占用,请更换端口号!!!");
                    ReListen(tcplistener);
                }
                Write(
    "确认:y/n (yes or no):");
                
    string isOK = Console.ReadLine();
                
    if (isOK == "y")
                {
                    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();
                        System.Threading.Thread.Sleep(
    10);
                        
    //启动线程 
                    }
                }
                
    else
                {
                    ReListen(tcplistener);
                }
            }
            
    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);
                }
            }
        }
    }

    本人测试:

    在打开IE-》工具->Internet选项->链接->局域网设置->代理连接-》输入IP和端口号

    访问网站,查看控制台输出消息,页面访问正常,测试通过。

    本来想测试下QQ代理,无奈本地已被封,服务器也没端口可用。有空回家再测了。

    提供代码下载

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    MMDrawerController(第三方类库)侧边栏的使用
    NSString 字符串的一些操作
    AVAudioPlayer实现音乐播放(AFSoundManager的简单介绍)
    歌词同步小控件
    豆瓣FM音乐播放器
    SDWebImage的简单使用
    用系统图标创建UITabBarController
    LeetCode 树(N叉树遍历和二叉树遍历及其他)
    《汇编语言》——王爽 第15章 外中断
    《汇编语言》——王爽 第14章 端口
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1750587.html
Copyright © 2020-2023  润新知