C#代理服务器不';我不能正常工作
我正在使用套接字在.NET的代理服务器上工作,我发现了对代码执行非常感兴趣的时刻: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
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循环来接收数据(其中一些数据可能已经准备好读取,但可能还不是全部)。