首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对简单代理服务器进行故障排除

对简单代理服务器进行故障排除
EN

Stack Overflow用户
提问于 2012-08-15 02:17:15
回答 1查看 373关注 0票数 1

我已经使用System.Net和System.Net.Sockets的同步方法和类用C#编写了一个简单的代理服务器。除了一个小故障之外,大多数事情都已经完成了。

当我从代理客户端(比如www.google.com)浏览url时,它可以很好地打开。当我做一个关键字搜索的时候,也没问题。但是,当我单击搜索结果时,客户端再次在屏幕上看到google.com主页!!但是,客户端浏览器url栏仍显示所单击的搜索结果url。也许这是因为google结果页面没有提供指向结果url的直接链接,而是指向google本身的链接,而我认为我代码中的中继逻辑无法处理这一点。你能帮我弄一下这个吗?我的代码如下:( ThreadHandleClient()方法是处理所有客户端请求并中继请求和响应的重要方法)

代码语言:javascript
复制
    public void Start(IPAddress ip, int port)
    {
        try
        {
            TcpListener listener = new TcpListener(ip, port);
            listener.Start(100);
            while (!stopFlag)
            {
                Socket client = listener.AcceptSocket();
                IPEndPoint rep = (IPEndPoint)client.RemoteEndPoint;
                Thread th = new Thread(ThreadHandleClient);
                th.Start(client);
            }

            listener.Stop();
        }
        catch (Exception ex)
        {
            Debug.Print("START: " + ex.Message);
        }
    }

    public void Stop()
    {
        stopFlag = true;    
    }

    public void ThreadHandleClient(object o)
    {
        try
        {
            Socket client = (Socket)o;
            Debug.Print("lingerstate=" + client.LingerState.Enabled.ToString() + " timeout=" + client.LingerState.LingerTime.ToString());
            NetworkStream ns = new NetworkStream(client);
            //RECEIVE CLIENT DATA
            byte[] buffer = new byte[2048];
            int rec = 0, sent = 0, transferred = 0, rport = 0;
            string data = "";
            do
            {
                rec = ns.Read(buffer, 0, buffer.Length);
                data += Encoding.ASCII.GetString(buffer, 0, rec);
            } while (rec == buffer.Length);

            //PARSE DESTINATION AND SEND REQUEST
            string line = data.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None)[0];
            Uri uri = new Uri(line.Split(new string[] { " " }, StringSplitOptions.None)[1]);
            Debug.Print("CLIENT REQUEST RECEIVED: " + uri.OriginalString);
            if (uri.Scheme == "https")
            {
                rport = 443;
                Debug.Print("HTTPS - 443");

                //rq = HttpVersion + " 200 Connection established\r\nProxy-Agent: Prahlad`s Proxy Server\r\n\r\n";
                //ClientSocket.BeginSend(Encoding.ASCII.GetBytes(rq), 0, rq.Length, SocketFlags.None, new AsyncCallback(this.OnOkSent), ClientSocket);
            }
            else
            {
                rport = 80;
                Debug.Print("HTTP - 443");
            }
            IPHostEntry rh = Dns.GetHostEntry(uri.Host);
            Socket webserver = new Socket(rh.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.IP);
            webserver.Connect(new IPEndPoint(rh.AddressList[0], rport));
            byte[] databytes = Encoding.ASCII.GetBytes(data);
            webserver.Send(databytes, databytes.Length, SocketFlags.None);
            Debug.Print("SENT TO SERVER. WILL NOW RELAY: " + data);

            //START RELAY
            buffer = new byte[2048];
            bool firstTime = true;
            rec = 0;
            data = "";
            do
            {
                transferred = 0;
                do
                {
                    if (webserver.Poll((firstTime ? 9000 : 2000) * 1000, SelectMode.SelectRead))
                    {
                        rec = webserver.Receive(buffer, buffer.Length, SocketFlags.None);
                        Debug.Print("RECEIVED FROM WEBSERVER[" + rec.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                        firstTime = false;
                        sent = client.Send(buffer, rec, SocketFlags.None);
                        Debug.Print("SENT TO CLIENT[" + sent.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                        transferred += rec;
                    }
                    else
                    {
                        Debug.Print("No data polled from webserver");
                    }
                } while (rec == buffer.Length);

                Debug.Print("loop-1 finished");

                //if (transferred == 0)
                //     break;

                //transferred = 0;
                rec = 0;
                do
                {
                    if (client.Poll(1000 * 1000, SelectMode.SelectRead))
                    {
                        rec = client.Receive(buffer, buffer.Length, SocketFlags.None);
                        Debug.Print("RECEIVED FROM CLIENT: " + Encoding.ASCII.GetString(buffer, 0, rec));

                        sent = webserver.Send(buffer, rec, SocketFlags.None);
                        Debug.Print("SENT TO WEBSERVER[" + sent.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                        transferred += rec;
                    }
                    else
                    {
                        Debug.Print("No data polled from client");
                    }
                } while (rec == buffer.Length);
                Debug.Print("loop-2 finished");

            } while (transferred > 0);
            Debug.Print("LOOP ENDS. EXITING THREAD");
            client.Close();
            webserver.Close();
        }
        catch (Exception ex)
        {
            Debug.Print("Error occured: " + ex.Message);
        }
        finally {
            Debug.Print("Client thread closed");
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-15 21:43:07

经过反复试验,我找到了解决方案,因此我回答了我自己的问题。我的中继逻辑的问题是它用于双向中继,即从webserver->client和client->webserver进行中继。我意识到转发第二部分可能会在重定向中带来麻烦,因为在重定向中,报头的url部分("GET http://debian.org HTTP/1.1")会突然改变,因此它将不同于被中继的web服务器!!例如,谷歌重定向指向debian.org,而代理仍然会中继来自google.com而不是debian.org的流量。为了避免这种情况,我删除了第二个中继部分(即client->webserver)。如果一个客户端发送了一个新的请求,最好在一个单独的线程中处理,这样它就会被定向到正确的url主机。所以,我所要做的就是注释掉我的中继逻辑中的第二个内部循环:

代码语言:javascript
复制
                //rec = 0;
                //do
                //{
                //    if (client.Poll(3000 * 1000, SelectMode.SelectRead))
                //    {
                //        rec = client.Receive(buffer, buffer.Length, SocketFlags.None);
                //        Debug.Print("RECEIVED FROM CLIENT: " + Encoding.ASCII.GetString(buffer, 0, rec));

                //        sent = webserver.Send(buffer, rec, SocketFlags.None);
                //        Debug.Print("SENT TO WEBSERVER[" + sent.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                //        transferred += rec;
                //    }
                //    else
                //    {
                //        Debug.Print("No data polled from client");
                //    }
                //} while (rec == buffer.Length);
                //Debug.Print("loop-2 finished");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11958350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档