私の他の質問に関連していますが、問題が解決することを期待して非同期を試しています。そうではありません。
シンプルな SOCKS5 サーバーを作成しようとしています。このプログラムをSOCKS5として使用するようにブラウザ(firefox)を設定しました。アイデアは、プログラムがプロキシサーバーに接続し、必要な情報を提供し、サーバーが単にある接続から別の接続へのデータの読み取り/書き込みを行うというものです。これは単にそれを行い、何も記録もフィルタリングもしません。非常にシンプルですが、CPUの問題と、数ページをヒットした後サイトに接続するのに数秒かかるという事実により、完全に使用できなくなります. 一体どうしてこれがそんなに多くの CPU を消費するのでしょうか? また、サイトへの接続に時間がかかるのはなぜですか? 非同期と同期の両方がこれに苦しんでいます
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Timers;
using System.IO;
using System.Net;
using System.Threading;
namespace ProxyTest
{
class Program
{
static ManualResetEvent tcpClientConnected =new ManualResetEvent(false);
static void Main(string[] args)
{
var s2 = new TcpListener(9998);
s2.Start();
Task.Run(() =>
{
while (true)
{
tcpClientConnected.Reset();
s2.BeginAcceptTcpClient(Blah, s2);
tcpClientConnected.WaitOne();
}
});
while (true)
System.Threading.Thread.Sleep(10000000);
}
static void Blah(IAsyncResult ar)
{
try
{
Console.WriteLine("Connection");
TcpListener listener = (TcpListener)ar.AsyncState;
using (var socketin = listener.EndAcceptTcpClient(ar))
{
tcpClientConnected.Set();
var ns1 = socketin.GetStream();
var r1 = new BinaryReader(ns1);
var w1 = new BinaryWriter(ns1);
if (false)
{
var s3 = new TcpClient();
s3.Connect("127.0.0.1", 9150);
var ns3 = s3.GetStream();
var r3 = new BinaryReader(ns3);
var w3 = new BinaryWriter(ns3);
while (true)
{
while (ns1.DataAvailable)
{
var b = ns1.ReadByte();
w3.Write((byte)b);
//Console.WriteLine("1: {0}", b);
}
while (ns3.DataAvailable)
{
var b = ns3.ReadByte();
w1.Write((byte)b);
Console.WriteLine("2: {0}", b);
}
}
}
{
if (!(r1.ReadByte() == 5 && r1.ReadByte() == 1))
return;
var c = r1.ReadByte();
for (int i = 0; i < c; ++i)
r1.ReadByte();
w1.Write((byte)5);
w1.Write((byte)0);
}
{
if (!(r1.ReadByte() == 5 && r1.ReadByte() == 1))
return;
if (r1.ReadByte() != 0)
return;
}
byte[] ipAddr = null;
string hostname = null;
var type = r1.ReadByte();
switch (type)
{
case 1:
ipAddr = r1.ReadBytes(4);
break;
case 3:
hostname = Encoding.ASCII.GetString(r1.ReadBytes(r1.ReadByte()));
break;
case 4:
throw new Exception();
}
var nhport = r1.ReadInt16();
var port = IPAddress.NetworkToHostOrder(nhport);
var socketout = new TcpClient();
if (hostname != null)
socketout.Connect(hostname, port);
else
socketout.Connect(new IPAddress(ipAddr), port);
w1.Write((byte)5);
w1.Write((byte)0);
w1.Write((byte)0);
w1.Write(type);
switch (type)
{
case 1:
w1.Write(ipAddr);
break;
case 2:
w1.Write((byte)hostname.Length);
w1.Write(Encoding.ASCII.GetBytes(hostname), 0, hostname.Length);
break;
}
w1.Write(nhport);
var buf1 = new byte[4096];
var buf2 = new byte[4096];
var ns2 = socketout.GetStream();
var r2 = new BinaryReader(ns2);
var w2 = new BinaryWriter(ns2);
Task.Run(() =>
{
var re = new ManualResetEvent(false);
while (true)
{
re.Reset();
ns1.BeginRead(buf1, 0, buf1.Length, ReadCallback, new A() { buf = buf1, thisSocket = socketin, otherSocket = socketout, thisStream = ns1, otherStream = ns2, re=re });
re.WaitOne();
}
});
Task.Run(() =>
{
var re = new ManualResetEvent(false);
while (true)
{
re.Reset();
ns2.BeginRead(buf2, 0, buf2.Length, ReadCallback, new A() { buf = buf2, thisSocket = socketout, otherSocket = socketin, thisStream = ns2, otherStream = ns1, re = re });
re.WaitOne();
}
});
while (true)
{
if (socketin.Connected == false)
return;
Thread.Sleep(100);
}
}
}
catch { }
}
class A { public byte[] buf; public TcpClient thisSocket, otherSocket; public NetworkStream thisStream, otherStream; public ManualResetEvent re;};
static void ReadCallback(IAsyncResult ar)
{
try
{
var a = (A)ar.AsyncState;
var ns1 = a.thisStream;
var len = ns1.EndRead(ar);
a.otherStream.Write(a.buf, 0, len);
a.re.Set();
}
catch
{
}
}
}
}