gpt4 book ai didi

c# - 通过代理连接到 IRC (.NET)

转载 作者:太空宇宙 更新时间:2023-11-03 15:55:19 25 4
gpt4 key购买 nike

我希望在通过我的 .NET 应用程序连接到 IRC 时隐藏我的 IP。我目前使用 IrcDotNet 库,但它似乎不支持代理。

我对套接字没有太多经验,所以我认为修改 IrcDotNet 比制作我自己的 IRC 库更容易。我四处寻找可以在 IrcDotNet 中实现的处理代理连接的套接字库。我找到了一个名为 ProxySocket 的,但它只支持 BeginConnect,不支持 IrcDotNet 使用的新 ASyncConnect 方法。

按优先顺序分解它,这就是我要找的东西;

  1. 支持通过 HTTP/SOCKS 代理连接的 IRC 库
  2. 一个支持通过 HTTP/SOCKS 代理连接的套接字库异步连接
  3. 关于如何扩展套接字类以支持连接的示例代码通过 HTTP/SOCKS 代理通过 ASyncConnect

我使用的 IrcDotNet 版本是 0.4.1,可以在 https://launchpad.net/ircdotnet 找到.

更新 1:恐怕仍然没有运气。 Fredrik92 的回答虽然有帮助,但不适用于我正在使用的 IrcDotNet 版本(见上文)。

最佳答案

IRC.NET 库使用 System.Net.Sockets 命名空间中的标准 Socket 类。

因此,您只需修改 IRC.NET 源代码 (@ http://ircdotnet.codeplex.com/SourceControl/latest) 中的 IrcDotNet/IrcClient.cs 文件即可。

您应该为启用代理的 IRC 客户端添加构造函数并调用默认构造函数。

然后您需要做的就是修改同一个文件中的连接方法(几乎在底部)。每次他们调用 this.client.BeginConnect(..) 时,您都必须添加用于连接到代理(而不是远程主机)的代码

现在您只需创建一个新的 Connect-callback 方法来向代理发送 HTTP CONNECT 请求。读取来自 HTTP 代理的响应,然后其他一切都应该工作。

在这种情况下,我会将 HTTP 请求作为原始 ASCII 字节写入代理(而不是使用 HttpWebRequest 类),以便您可以完全控制作为返回获得的网络流...

你应该添加某事。像这样到 IrcClient 类:

private bool useProxy = false;
private IWebProxy proxy;
private IEnumerable<Uri> proxyRemoteUris;

public IrcClient(IWebProxy proxy)
: this()
{
this.useProxy = true;
this.proxy = proxy;
}

private void ProxyPerformHttpConnect(Uri remoteIrcUri)
{
string httpConnectRequest = string.Format("CONNECT {0}:{1} HTTP/1.1\r\nHost: {2}\r\n\r\n",
remoteIrcUri.Host, remoteIrcUri.Port, this.proxy.GetProxy(remoteIrcUri));
byte[] httpConnectData = Encoding.ASCII.GetBytes(httpConnectRequest);

this.stream.Write(httpConnectData, 0, httpConnectData.Length);

bool responseReady = false;
string responseText = string.Empty;
// Byte-by-byte reading required, because StringReader will read more than just the HTTP response header
do
{
int readByte = this.stream.ReadByte();
if (readByte < 0)
throw new WebException(message: null, status: WebExceptionStatus.ConnectionClosed);

char readChar = (char)(readByte); // Only works because HTTP Headers are ASCII encoded.
responseText += readChar;

responseReady = responseText.EndsWith("\r\n\r\n");
} while (!responseReady);

int statusStart = responseText.IndexOf(' ') + 1;
int reasonStart = responseText.IndexOf(' ', statusStart) + 1;
int reasonEnd = responseText.IndexOfAny(new char[] { '\r', '\n'});
HttpStatusCode responseStatus = (HttpStatusCode)(int.Parse(responseText.Substring(responseText.IndexOf(' ') + 1, length: 3)));
if (responseStatus != HttpStatusCode.OK)
{
string reasonText = responseText.Substring(reasonStart, reasonEnd - reasonStart);
if (string.IsNullOrWhiteSpace(reasonText))
reasonText = null;
throw new WebException(reasonText, WebExceptionStatus.ConnectFailure);
}

// Finished Response Header read...
}

private void ProxyConnectCallback(IAsyncResult ar)
{
try
{
this.client.EndConnect(ar);
this.stream = this.client.GetStream();

bool proxyTunnelEstablished = false;
WebException lastWebException = null;
foreach (Uri remoteIrcUri in this.proxyRemoteUris)
{
if (this.client.Connected == false)
{
// Re-establish connection with proxy...
Uri proxyUri = this.proxy.GetProxy(remoteIrcUri);
this.client.Connect(proxyUri.Host, proxyUri.Port);
}

try
{
ProxyPerformHttpConnect(remoteIrcUri);
proxyTunnelEstablished = true;
break;
}
catch (WebException webExcept)
{
lastWebException = webExcept;
}
}

if (!proxyTunnelEstablished)
{
OnConnectFailed(new IrcErrorEventArgs(lastWebException));
return;
}

this.writer = new StreamWriter(this.stream, Encoding.Default);
this.reader = new StreamReader(this.stream, Encoding.Default);

HandleClientConnected((IrcRegistrationInfo)ar.AsyncState);
this.readThread.Start();
this.writeThread.Start();

OnConnected(new EventArgs());
}
catch (Exception ex)
{
OnConnectFailed(new IrcErrorEventArgs(ex));
}
}

IrcClient 类的所有 Connect 方法中的代理处理代码因此看起来……像这样:

// Code snippet to insert before the call to this.client.BeginConnect(...)
if (this.useProxy)
{
// Assign host and port variables for EndPoint objects:
// var host = remoteEP.Address;
// var port = remoteEP.Port;
this.proxyRemoteUris = new Uri[] { new Uri(string.Format("irc://{0}:{1}/", host, port)) };
// Replace the line above with the following line in the method where an array of IP addresses is specified as a parameter
// this.proxyRemoteUris = from ip in addresses select new Uri(string.Format("irc://{0}:{1}/", ip, port));
Uri proxyUri = this.proxy.GetProxy(this.proxyRemoteUris.First());
string proxyHost = proxyUri.Host;
int proxyPort = proxyUri.Port;
this.client.BeginConnect(proxyHost, proxyPort, ProxyConnectCallback, registrationInfo);
}
else
// Original this.client.BeginConnect(...) call here...

关于c# - 通过代理连接到 IRC (.NET),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23905664/

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