C#代理服务器不';我不能正常工作

C#代理服务器不';我不能正常工作,c#,sockets,.net-3.5,proxy,C#,Sockets,.net 3.5,Proxy,我正在使用套接字在.NET的代理服务器上工作,我发现了对代码执行非常感兴趣的时刻: 当我一步一步地调试代码时,代理服务器工作正常 当我在没有调试的情况下启动代理服务器时,浏览器中会出现错误 我真的不知道为什么它像我上面描述的那样工作。也许有人已经解决了这个问题 以下是我的代理服务器的代码: using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System

我正在使用套接字在.NET的代理服务器上工作,我发现了对代码执行非常感兴趣的时刻:

  • 当我一步一步地调试代码时,代理服务器工作正常
  • 当我在没有调试的情况下启动代理服务器时,浏览器中会出现错误
  • 我真的不知道为什么它像我上面描述的那样工作。也许有人已经解决了这个问题

    以下是我的代理服务器的代码:

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    
    namespace Statistiks.Lib
    {
        internal class NetworkMonitor
        {
            private readonly IList<string> _denied;
            private readonly Socket _srvSocket;
            private readonly Thread _srvThread;
    
            public NetworkMonitor(int port, IList<string> deniedList)
            {
                _denied = deniedList;
                _srvSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                                        ProtocolType.Tcp);
                _srvSocket.Bind(new IPEndPoint(IPAddress.Loopback, port));
                _srvThread = new Thread(ProxyServerThread);
                _srvThread.Start(_srvSocket);
            }
    
            private void ProxyServerThread(object obj)
            {
                var srv = obj as Socket;
                srv.Listen(1024);
                while (true)
                {
                    Socket clientSocket = srv.Accept();
                    ThreadPool.QueueUserWorkItem(cSocket =>
                        {
                            var client = cSocket as Socket;
                            if (client.Available <= 0)
                            {
                                client.Shutdown(SocketShutdown.Both);
                                client.Close();
                                return;
                            }
                            var recieveBuf = new byte[client.Available];
                            client.Receive(recieveBuf, SocketFlags.None);
                            var ni = new NetworkInfo();
                            try
                            {
                                ni.Url = new Uri(Encoding.ASCII.GetString(recieveBuf)
                                                         .Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries)[0]
                                                     .Split(' ')[1]);
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                client.Shutdown(SocketShutdown.Both);
                                client.Close();
                                return;
                            }
                            var forwardedSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                                                             ProtocolType.Tcp);
                            forwardedSocket.Connect(Dns.GetHostAddresses(ni.Url.Host)[0], ni.Url.Port);
                            forwardedSocket.Send(recieveBuf, SocketFlags.None);
                            recieveBuf = new byte[forwardedSocket.Available];
                            forwardedSocket.Receive(recieveBuf, SocketFlags.None);
                            client.Send(recieveBuf, SocketFlags.None);
                            forwardedSocket.Shutdown(SocketShutdown.Both);
                            forwardedSocket.Disconnect(false);
                            client.Shutdown(SocketShutdown.Both);
                            client.Disconnect(false);
                            forwardedSocket.Close();
                            client.Close();
                        }, clientSocket);
                }
            }
        }
    
        internal struct NetworkInfo
        {
            internal Uri Url;
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    Net系统;
    使用System.Net.Sockets;
    使用系统文本;
    使用系统线程;
    命名空间Statistiks.Lib
    {
    内部类网络监视器
    {
    私有只读IList被拒绝;
    专用只读套接字_srvSocket;
    私有只读线程_srvThread;
    公用网络监视器(int端口,IList拒绝列表)
    {
    _拒绝=拒绝列表;
    _srvSocket=新套接字(AddressFamily.InterNetwork、SocketType.Stream、,
    原型(Tcp);
    _绑定(新的IPEndPoint(IPAddress.Loopback,port));
    _srvThread=新线程(ProxyServerThread);
    _srvThread.Start(_srvSocket);
    }
    私有void ProxyServerThread(对象obj)
    {
    var srv=obj as插座;
    srv.Listen(1024);
    while(true)
    {
    Socket clientSocket=srv.Accept();
    ThreadPool.QueueUserWorkItem(cSocket=>
    {
    var client=cSocket作为套接字;
    
    if(client.Available调试器下的不同结果可能是因为您的所有数据都适合套接字缓冲区,并且调试的额外延迟允许所有数据在调用
    Receive
    之前到达

    但是,在正常执行情况下,情况并非如此。数据将以数据包的形式到达,为了知道数据的结尾在哪里,您必须解析您的HTTP请求。Socket的
    Available
    属性仅指示当前缓冲区中有多少数据,而不是整个消息的长度。虽然它肯定是可能的能够使用原始套接字进行读取,使用
    网络流

    IEnumerable<string> ReadRequestHeaders(Socket s)
    {
        using (var stream = new NetworkStream(s, false))
        using (var reader = new StreamReader(stream))
        {
            while (true)
            {
                var line = reader.ReadLine();
                if (line == "")
                    break;
    
                yield return line;
            }
        }
    }
    
    IEnumerable ReadRequestHeader(套接字)
    {
    使用(var流=新网络流(s,false))
    使用(变量读取器=新的流读取器(流))
    {
    while(true)
    {
    var line=reader.ReadLine();
    如果(行==“”)
    打破
    收益率回归线;
    }
    }
    }
    

    HTTP消息的其余部分也是如此-为了正确转发它,您必须知道它的结束位置,这意味着要理解内容长度或传输编码字段并进行相应的解析。

    听起来像是一个计时问题。很可能是在收到任何数据之前检查可用数据,导致连接中断丢失。另外,使用while循环来接收数据(其中一些数据可能已经准备好读取,但可能还不是全部)。