无法从代理C#获得完整响应

时间:2012-11-15 10:29:11

标签: c# http proxy

我正在构建一个在浏览器和squid代理之间运行的小型HTTP代理。浏览器将HTTP请求发送到我的代理,将其重定向到squid代理,然后我的应用程序从squid代理获取响应并将其返回给浏览器。

问题是我无法从代理获得完整的响应,我得到HTTP 200 OK ...(只是响应头),但随着身体然后我必须再次调用接收方法获取身体。但如果我调试我的代码(使应用程序变慢)它获得所有响应(响应标题和正文) 在TCPClass中是否有任何适当的指示我远程服务器仍然有数据发送给我? 这是我的代码:

static void Main(string[] args)
    {
        int ServerPort = 8888;
        IPAddress localHost = new IPAddress(0x0100007f);
        TcpListener listener = new TcpListener(localHost,ServerPort);
        listener.Start();
        while(true)
        {
            string requestString = "";
            String respenseString = "";
            TcpClient application = listener.AcceptTcpClient();
            string source = application.Client.RemoteEndPoint.ToString();
            byte[] dataFromApp = new byte[application.ReceiveBufferSize];
            application.Client.Receive(dataFromApp);                
            TcpClient tunnel = new TcpClient("127.0.0.1",8080);
            tunnel.Client.Send(dataFromApp);                
            while (tunnel.Client.Connected ==true)
            {
                if(tunnel.Available != 0)
                {                        
                    byte[] responseFromProxy = new byte[tunnel.ReceiveBufferSize];
                    tunnel.Client.Receive(responseFromProxy);
                    respenseString += Encoding.UTF8.GetString(responseFromProxy);
                }
                else
                {                        
                    break;
                }
            }                
            application.Client.Send(Encoding.UTF8.GetBytes(respenseString));
        }

3 个答案:

答案 0 :(得分:1)

您应该检查tunnel.Client.Receiveapplication.Client.Receive的返回值。 Receive并不保证会读取 dataFromApp.Length bytes

  

备注:Receive方法将数据读入buffer参数并返回成功读取的字节数

PS:您可能还想尝试FiddlerCore来编写Http代理

答案 1 :(得分:0)

没有“套接字上的此消息”属性还剩N个字节,因为TCP套接字正在流式传输:它发送和接收字节,而不是消息。

HTTP定义消息,如果要实现HTTP代理,则应熟悉HTTP 1.1 RFC。有多种方法可以确定lenght of an HTTP message,所有这些都必须实现,以确保您可以成功接收和发送HTTP消息。

答案 2 :(得分:-1)

谢谢你们

我做到了:

while (tunnel.Client.Receive(oneByte) != 0)
{
  byte[] responseFromProxy = new byte[tunnel.Available];
  tunnel.Client.Receive(responseFromProxy);
  application.Client.Send(oneByte);
  application.Client.Send(responseFromProxy);
}