gpt4 book ai didi

使用 TCP 的 C# HTTPS 代理

转载 作者:行者123 更新时间:2023-11-30 20:55:26 27 4
gpt4 key购买 nike

我正在尝试使用 C# 实现 HTTPS 代理。代理应该只支持 HTTPS,而不是 HTTP。据我所知,HTTPListener 不是一个好的选择,因为您需要 SSL 证书才能支持 HTTPS,而代理通常不提供。

我正在使用 TcpListener 和 TcpClients。这是我到目前为止得到的代码:

   protected void HandleTCPRequest(object clientObject)
{
TcpClient inClient = clientObject as TcpClient;
TcpClient outClient = null;

try
{
NetworkStream clientStream = inClient.GetStream();
StreamReader clientReader = new StreamReader(clientStream);
StreamWriter clientWriter = new StreamWriter(clientStream);

// Read initial request.
List<String> connectRequest = new List<string>();
string line;
while (!String.IsNullOrEmpty(line = clientReader.ReadLine()))
{
connectRequest.Add(line);
}
if (connectRequest.Count == 0)
{
return;
}

string[] requestLine0Split = connectRequest[0].Split(' ');
if (requestLine0Split.Length < 3)
{
return;
}
// Check if it is CONNECT
string method = requestLine0Split[0];
if (!method.Equals("CONNECT"))
{
return;
}
// Get host and port
string requestUri = requestLine0Split[1];
string[] uriSplit = requestUri.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (uriSplit.Length < 2)
{
return;
}
string host = uriSplit[0];
int port = Int32.Parse(uriSplit[1]);

// Connect to server
outClient = new TcpClient(host, port);
NetworkStream serverStream = outClient.GetStream();
StreamWriter serverWriter = new StreamWriter(serverStream);
StreamReader serverReader = new StreamReader(serverStream);

// Send 200 Connection Established to Client
clientWriter.WriteLine("HTTP/1.0 200 Connection established\r\n\r\n");
clientWriter.Flush();

Logger.Debug("Established TCP connection for " + host);

while (true)
{
line = clientReader.ReadLine();
if (line != null)
{
Logger.Debug("->Server: " + line);
serverWriter.WriteLine(line);
}
line = serverReader.ReadLine();
if (line != null)
{
Logger.Debug("->Client: " + line);
clientWriter.WriteLine(line);
}
}
}
catch(Exception)
{
// Disconnent if connections still alive
try
{
if (inClient.Connected)
{
inClient.Close();
}
if (outClient != null && outClient.Connected)
{
outClient.Close();
}
}
catch (Exception e)
{
Logger.Warn("Could not close the tcp connection: ", e);
}
}
}

传入的连接在另一种方法中被接受。

编辑:我做了一些改动。现在,客户端开始发送 SSL 数据,但服务器从未响应。一段时间后,客户端打开一个新连接并再次尝试。我得到的输出:

Established TCP connection for www.google.de
->Server: ▬♥☺ ?☺ ?♥☺R'"??????#☼}~??♣|]?
->Server: ??_5OL(?? H ??
->Server: ?¶ ? ? 9 8?☼?♣ ? 5?? ?◄?‼ E D 3 2?♀?♫?☻?♦ ? A ♣ ♦ /?↕ ▬ ‼?
->Server: ?♥??
->Server: ☺ 0 ↕ ►
->Server: www.google.de
->Server: ♠ ↨ ↑ ↓ ♂ ☻☺ # 3t

除了 TCP 监听器之外,我愿意接受其他建议。谢谢!

最佳答案

开始工作了。使用 StreamReader/StreamWriter 处理 SSL 数据是错误的。数据被转换为字符串,因此出现错误(我假设)。将 NetworkStream.ReadNetworkStream.Write 方法与 byte[] 一起使用。

代码如下:

    /// <summary>
/// Handles a TCP request.
/// </summary>
/// <param name="clientObject">The tcp client from the accepted connection.</param>
protected void HandleTCPRequest(object clientObject)
{
TcpClient inClient = clientObject as TcpClient;
TcpClient outClient = null;

try
{
NetworkStream clientStream = inClient.GetStream();
StreamReader clientReader = new StreamReader(clientStream);
StreamWriter clientWriter = new StreamWriter(clientStream);

// Read initial request.
List<String> connectRequest = new List<string>();
string line;
while (!String.IsNullOrEmpty(line = clientReader.ReadLine()))
{
connectRequest.Add(line);
}
if (connectRequest.Count == 0)
{
throw new Exception();
}

string[] requestLine0Split = connectRequest[0].Split(' ');
if (requestLine0Split.Length < 3)
{
throw new Exception();
}
// Check if it is CONNECT
string method = requestLine0Split[0];
if (!method.Equals("CONNECT"))
{
throw new Exception();
}
// Get host and port
string requestUri = requestLine0Split[1];
string[] uriSplit = requestUri.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (uriSplit.Length < 2)
{
throw new Exception();
}
string host = uriSplit[0];
int port = Int32.Parse(uriSplit[1]);

// Connect to server
outClient = new TcpClient(host, port);

// Send 200 Connection Established to Client
clientWriter.WriteLine("HTTP/1.0 200 Connection established\r\n\r\n");
clientWriter.Flush();

Logger.Debug("Established TCP connection for " + host + ":" + port);

Thread clientThread = new Thread(() => TunnelTCP(inClient, outClient));
Thread serverThread = new Thread(() => TunnelTCP(outClient, inClient));

clientThread.Start();
serverThread.Start();
}
catch(Exception)
{
// Disconnent if connections still alive
Logger.Debug("Closing TCP connection.");
try
{
if (inClient.Connected)
{
inClient.Close();
}
if (outClient != null && outClient.Connected)
{
outClient.Close();
}
}
catch (Exception e)
{
Logger.Warn("Could not close the tcp connection: ", e);
}
}
}

/// <summary>
/// Tunnels a TCP connection.
/// </summary>
/// <param name="inClient">The client to read from.</param>
/// <param name="outClient">The client to write to.</param>
public void TunnelTCP(TcpClient inClient, TcpClient outClient)
{
NetworkStream inStream = inClient.GetStream();
NetworkStream outStream = outClient.GetStream();
byte[] buffer = new byte[1024];
int read;
try
{
while (inClient.Connected && outClient.Connected)
{
if (inStream.DataAvailable && (read = inStream.Read(buffer, 0, buffer.Length)) != 0)
{
outStream.Write(buffer, 0, read);
}
}
}
catch (Exception e)
{
Logger.Debug("TCP connection error: ", e);
}
finally
{
Logger.Debug("Closing TCP connection.");
// Disconnent if connections still alive
try
{
if (inClient.Connected)
{
inClient.Close();
}
if (outClient.Connected)
{
outClient.Close();
}
}
catch (Exception e1)
{
Logger.Warn("Could not close the tcp connection: ", e1);
}
}
}

关于使用 TCP 的 C# HTTPS 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18307932/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com