我正在使用套接字在 .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;
}
}