我试图stunnel
在 C# 中进行克隆只是为了好玩。主循环是这样的(暂时忽略 catch-everything-and-do-nothing try-catch)
ServicePointManager.ServerCertificateValidationCallback = Validator;
TcpListener a = new TcpListener (9999);
a.Start ();
while (true) {
Console.Error.WriteLine ("Spinning...");
try {
TcpClient remote = new TcpClient ("XXX.XX.XXX.XXX", 2376);
SslStream ssl = new SslStream(remote.GetStream(), false, new RemoteCertificateValidationCallback(Validator));
ssl.AuthenticateAsClient("mirai.ca");
TcpClient user = a.AcceptTcpClient ();
new Thread (new ThreadStart(() => {
Thread.CurrentThread.IsBackground = true;
try{
forward(user.GetStream(), ssl); //forward is a blocking function I wrote
}catch{}
})).Start ();
} catch {
Thread.Sleep (1000);
}
}
我发现,如果我像我一样在等待用户之前进行远程 SSL 连接,那么当用户连接时,SSL 已经设置好(这是用于隧道 HTTP,因此延迟非常重要)。另一方面,我的服务器关闭了长时间不活动的连接,所以如果在 5 分钟内没有新连接发生,一切都会锁定。
什么是最好的方法?
另外,我观察到我的程序生成了多达 200 个线程,这当然意味着上下文切换开销非常大,有时甚至会导致整个程序阻塞几秒钟,即使只有一个用户通过程序隧道。简而言之,我的转发功能就像
new Thread(new ThreadStart(()=>in.CopyTo(out))).Start();
out.CopyTo(in);
当然有很多错误处理,以防止断开的连接永远保持不变。不过,这似乎停滞了很多。我不知道如何使用异步方法BeginRead
,比如根据谷歌应该有帮助的方法。