C++/CLI HTTP 代理问题

发布于 2024-08-27 22:37:46 字数 5805 浏览 5 评论 0原文

我正在尝试(非常努力)制作一个小型 HTTP 代理服务器,我可以用它来将所有通信保存到文件中。由于我在该领域没有任何经验,因此我使用了 codeproject.com 中的一个类和一些相关代码来开始(它是用旧的 CLI 语法制作的,所以我对其进行了转换)。我无法让它工作,所以我添加了更多代码来使其工作(线程等),现在它可以工作了。基本上,它从客户端接收一些内容(我刚刚将 Mozilla Firefox 配置为通过此代理路由其连接),然后将其路由到 google.com。将 Firefox 的数据发送给 google 后,收到响应并将其发送给 Firefox。这工作正常,但代理无法从 Firefox 接收任何数据。它只是在 Sleep(50) 部分循环。不管怎样,代码如下:

ProxyTest.cpp:

#include "stdafx.h"
#include "windows.h"
#include "CHTTPProxy.h"

public ref class ClientThread {
public:
    System::Net::Sockets::TcpClient ^ pClient;
    CHttpProxy ^ pProxy;
    System::Int32 ^ pRecieveBufferSize;
    System::Threading::Thread ^ Thread;
    ClientThread(System::Net::Sockets::TcpClient ^ sClient,
                 CHttpProxy ^ sProxy,
                 System::Int32 ^ sRecieveBufferSize) {
        pClient = sClient;
        pProxy = sProxy;
        pRecieveBufferSize = sRecieveBufferSize;
    };
    void StartReading() {
        Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&ClientThread::ThreadEntryPoint));
        Thread->Start();
    };
    void ThreadEntryPoint() {
        char * bytess;
        bytess = new char[(int)pRecieveBufferSize];
        memset(bytess, 0, (int)pRecieveBufferSize);
        array<unsigned char> ^ bytes = gcnew array<unsigned char>((int)pRecieveBufferSize);
        array<unsigned char> ^ sendbytes;
        do {
            if (pClient->GetStream()->DataAvailable) {
                try {
                    do {
                        Sleep(100); //Lets wait for whole packet to get cached (If it even does...)
                        unsigned int k = pClient->GetStream()->Read(bytes, 0, (int)pRecieveBufferSize); //Read it
                        for (unsigned int i=0; i<(int)pRecieveBufferSize; i++) bytess[i] = bytes[i];
                        Console::WriteLine("Packet Received:\n"+gcnew System::String(bytess));
                        pProxy->SendToServer(bytes,pClient->GetStream()); //Now send it to google!

                    } while (pClient->GetStream()->DataAvailable);
                } catch (Exception ^ e) {
                    break;
                }
            } else {
                Sleep(50);
                if (!(pClient->Connected)) break;
            };
        } while (pClient->GetStream()->CanRead);
        delete [] bytess;
        pClient->Close();
    };
};
int main(array<System::String ^> ^args)
{
    System::Collections::Generic::Stack<ClientThread ^> ^ Clients =
        gcnew System::Collections::Generic::Stack<ClientThread ^>();

    System::Net::Sockets::TcpListener ^ pTcpListener = gcnew System::Net::Sockets::TcpListener(8080);

    pTcpListener->Start();
    System::Net::Sockets::TcpClient ^ pTcpClient;
    while (1) {
        pTcpClient = pTcpListener->AcceptTcpClient(); //Wait for client

        ClientThread ^ Client = gcnew ClientThread(pTcpClient,
                                gcnew CHttpProxy("www.google.com.au", 80),
                                pTcpClient->ReceiveBufferSize); //Make a new object for this client

        Client->StartReading(); //Start the thread
        Clients->Push(Client); //Add it to the list
    };
    pTcpListener->Stop();
    return 0;
}

CHTTPProxy.h,来自http://www.codeproject.com/KB/IP/howtoproxy.aspx 进行了大量修改:

#using <mscorlib.dll>
#using <SYSTEM.DLL>
using namespace System;
using System::Net::Sockets::TcpClient;
using System::String;
using System::Exception;
using System::Net::Sockets::NetworkStream;
#include <stdio.h>

ref class CHttpProxy 
{ 
public: 
    CHttpProxy(System::String ^ szHost, int port); 
    System::String ^ m_host; 
    int m_port; 
    void SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr); 
};

CHttpProxy::CHttpProxy(System::String ^ szHost, int port)
{
    m_host = gcnew System::String(szHost);
    m_port = port;
}

void CHttpProxy::SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr)
{
    TcpClient ^ tcpclnt = gcnew TcpClient();

    try
    {
        tcpclnt->Connect(m_host,m_port); 
    }
    catch (Exception ^ e )
    {
        Console::WriteLine(e->ToString());
        return;
    }

    // Send it
    if ( tcpclnt )
    {
        NetworkStream ^ networkStream;

        networkStream = tcpclnt->GetStream();

        int size = Packet->Length;        
        networkStream->Write(Packet, 0, size);
        array<unsigned char> ^ bytes = gcnew array<unsigned char>(tcpclnt->ReceiveBufferSize);
        char * bytess = new char[tcpclnt->ReceiveBufferSize];
        Sleep(500); //Wait for responce 
        do {
            unsigned int k = networkStream->Read(bytes, 0, (int)tcpclnt->ReceiveBufferSize); //Read from google

            for(unsigned int i=0; i<k; i++) {
                bytess[i] = bytes[i];
                if (bytess[i] == 0) bytess[i] = ' '; //Dont terminate the string
                if (bytess[i] < 8) bytess[i] = ' '; //Somethings making the computer beep, and its not 7?!?!
            };
            Console::WriteLine("\n\nAbove packet sent to google. Google Packet Received:\n"+gcnew System::String(bytess)); 

            sendstr->Write(bytes,0,k); //Send it to mozilla

            Console::WriteLine("\n\nAbove packet sent to client..."); 
            //Sleep(1000);

        } while(networkStream->DataAvailable);

        delete [] bytess;
    }
    return;
}

任何帮助将不胜感激,我已经尝试了几个小时。 (对缩进 nobugz 感到抱歉,现已修复)

I'm trying(very hard) to make a small HTTP Proxy server which I can use to save all communications to a file. Seeing as I dont really have any experience in the area, I used a class from codeproject.com and some associated code to get started (It was made in the old CLI syntax, so I converted it). I couldn't get it working, so I added lots more code to make it work (threads etc), and now it sort of works. Basically, it recieves something from a client (I just configured Mozilla Firefox to route its connections through this proxy) and then routes it to google.com. After it sends Firefox's data to google, recieves a responce, and sends that to Firefox. This works fine, but then the proxy fails to recieve any data from Firefox. It just loops in the Sleep(50) section. Anyway, heres the code:

ProxyTest.cpp:

#include "stdafx.h"
#include "windows.h"
#include "CHTTPProxy.h"

public ref class ClientThread {
public:
    System::Net::Sockets::TcpClient ^ pClient;
    CHttpProxy ^ pProxy;
    System::Int32 ^ pRecieveBufferSize;
    System::Threading::Thread ^ Thread;
    ClientThread(System::Net::Sockets::TcpClient ^ sClient,
                 CHttpProxy ^ sProxy,
                 System::Int32 ^ sRecieveBufferSize) {
        pClient = sClient;
        pProxy = sProxy;
        pRecieveBufferSize = sRecieveBufferSize;
    };
    void StartReading() {
        Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&ClientThread::ThreadEntryPoint));
        Thread->Start();
    };
    void ThreadEntryPoint() {
        char * bytess;
        bytess = new char[(int)pRecieveBufferSize];
        memset(bytess, 0, (int)pRecieveBufferSize);
        array<unsigned char> ^ bytes = gcnew array<unsigned char>((int)pRecieveBufferSize);
        array<unsigned char> ^ sendbytes;
        do {
            if (pClient->GetStream()->DataAvailable) {
                try {
                    do {
                        Sleep(100); //Lets wait for whole packet to get cached (If it even does...)
                        unsigned int k = pClient->GetStream()->Read(bytes, 0, (int)pRecieveBufferSize); //Read it
                        for (unsigned int i=0; i<(int)pRecieveBufferSize; i++) bytess[i] = bytes[i];
                        Console::WriteLine("Packet Received:\n"+gcnew System::String(bytess));
                        pProxy->SendToServer(bytes,pClient->GetStream()); //Now send it to google!

                    } while (pClient->GetStream()->DataAvailable);
                } catch (Exception ^ e) {
                    break;
                }
            } else {
                Sleep(50);
                if (!(pClient->Connected)) break;
            };
        } while (pClient->GetStream()->CanRead);
        delete [] bytess;
        pClient->Close();
    };
};
int main(array<System::String ^> ^args)
{
    System::Collections::Generic::Stack<ClientThread ^> ^ Clients =
        gcnew System::Collections::Generic::Stack<ClientThread ^>();

    System::Net::Sockets::TcpListener ^ pTcpListener = gcnew System::Net::Sockets::TcpListener(8080);

    pTcpListener->Start();
    System::Net::Sockets::TcpClient ^ pTcpClient;
    while (1) {
        pTcpClient = pTcpListener->AcceptTcpClient(); //Wait for client

        ClientThread ^ Client = gcnew ClientThread(pTcpClient,
                                gcnew CHttpProxy("www.google.com.au", 80),
                                pTcpClient->ReceiveBufferSize); //Make a new object for this client

        Client->StartReading(); //Start the thread
        Clients->Push(Client); //Add it to the list
    };
    pTcpListener->Stop();
    return 0;
}

CHTTPProxy.h, from http://www.codeproject.com/KB/IP/howtoproxy.aspx with a lot of modifications:

#using <mscorlib.dll>
#using <SYSTEM.DLL>
using namespace System;
using System::Net::Sockets::TcpClient;
using System::String;
using System::Exception;
using System::Net::Sockets::NetworkStream;
#include <stdio.h>

ref class CHttpProxy 
{ 
public: 
    CHttpProxy(System::String ^ szHost, int port); 
    System::String ^ m_host; 
    int m_port; 
    void SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr); 
};

CHttpProxy::CHttpProxy(System::String ^ szHost, int port)
{
    m_host = gcnew System::String(szHost);
    m_port = port;
}

void CHttpProxy::SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr)
{
    TcpClient ^ tcpclnt = gcnew TcpClient();

    try
    {
        tcpclnt->Connect(m_host,m_port); 
    }
    catch (Exception ^ e )
    {
        Console::WriteLine(e->ToString());
        return;
    }

    // Send it
    if ( tcpclnt )
    {
        NetworkStream ^ networkStream;

        networkStream = tcpclnt->GetStream();

        int size = Packet->Length;        
        networkStream->Write(Packet, 0, size);
        array<unsigned char> ^ bytes = gcnew array<unsigned char>(tcpclnt->ReceiveBufferSize);
        char * bytess = new char[tcpclnt->ReceiveBufferSize];
        Sleep(500); //Wait for responce 
        do {
            unsigned int k = networkStream->Read(bytes, 0, (int)tcpclnt->ReceiveBufferSize); //Read from google

            for(unsigned int i=0; i<k; i++) {
                bytess[i] = bytes[i];
                if (bytess[i] == 0) bytess[i] = ' '; //Dont terminate the string
                if (bytess[i] < 8) bytess[i] = ' '; //Somethings making the computer beep, and its not 7?!?!
            };
            Console::WriteLine("\n\nAbove packet sent to google. Google Packet Received:\n"+gcnew System::String(bytess)); 

            sendstr->Write(bytes,0,k); //Send it to mozilla

            Console::WriteLine("\n\nAbove packet sent to client..."); 
            //Sleep(1000);

        } while(networkStream->DataAvailable);

        delete [] bytess;
    }
    return;
}

Any help would be much appreciated, I've tried for hours. (Sorry about the indents nobugz, its fixed now)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文