使用tlsharp设置代理

时间:2017-08-10 13:44:37

标签: c# telegram

我正在尝试使用Telegram和TLSharp发送消息,这就是我到目前为止所做的:

static async void MainAssincrono(string[] args)
        {
            IniciarVariaveis();

            TelegramClient client;
            TcpClient tcp = conectarProxy(httpProxyHost, httpProxyPort);
            client = new TelegramClient(appId, appHash);
            await client.ConnectAsync();

            if (habilitarClient)
            {
                var hashAuth = await client.SendCodeRequestAsync(apiPhone);
                Console.WriteLine("Digite o código recebido no telegram do celular: ");
                var code = Console.ReadLine();
                var user = await client.MakeAuthAsync(apiPhone, hashAuth, code);
            }
            else
            {
                var resultado = await client.GetContactsAsync();
                var user = resultado.users.lists.Where(x => x.GetType() == typeof(TLUser)).Cast<TLUser>().FirstOrDefault(x => x.phone == "5581971126655");
                await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "Teste");
            }

它有效,但我正在尝试设置代理。这就是我想要做的事情:

TcpClient tcp = conectarProxy(httpProxyHost, httpProxyPort);
            client = new TelegramClient(appId, appHash, null, null, new TcpClientConnectionHandler(tcp);

private static TcpClient conectarProxy(string httpProxyHost, int httpProxyPort)
        {
            var url = "http://" + httpProxyHost + ":" + httpProxyPort;
            var proxyUrl = WebRequest.DefaultWebProxy.GetProxy(new Uri(url));
            WebResponse response = null;
            var tentativas = 10;

            while (tentativas >= 0)
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.KeepAlive = true;
                var webProxy = new WebProxy(proxyUrl);
                request.Proxy = webProxy;
                request.Method = "CONNECT";
                request.Timeout = 3000;

                tentativas--;
                try
                {
                    response = request.GetResponse();
                    break;
                }
                catch (Exception ex)
                {
                    if (tentativas >= 0 && ex.Message.Equals("The operation has timed out", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Console.WriteLine("Ocorreu timeout ao tentar se conectar pelo proxy.");
                    }
                    else
                    {
                        throw new Exception("Algo deu errado", ex);
                    }
                }
            }
            var responseStream = response.GetResponseStream();
            Debug.Assert(responseStream != null);

            const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Instance;

            var rsType = responseStream.GetType();
            var connectionProperty = rsType.GetProperty("Connection", Flags);

            var connection = connectionProperty.GetValue(responseStream, null);
            var connectionType = connection.GetType();
            var networkStreamProperty = connectionType.GetProperty("NetworkStream", Flags);

            var networkStream = networkStreamProperty.GetValue(connection, null);
            var nsType = networkStream.GetType();
            var socketProperty = nsType.GetProperty("Socket", Flags);
            var socket = (Socket)socketProperty.GetValue(networkStream, null);

            return new TcpClient { Client = socket };
        }

签名表示它期望TcpClientConnectionHandler作为参数,但是如果我传递这样的TcpClientConnectionHandler:

client = new TelegramClient(appId, appHash, null, null, new TcpClientConnectionHandler(tcp));

我给出一个错误,说它的tpc是一个变量,但它被用作方法。我做错了什么?

2 个答案:

答案 0 :(得分:3)

用于https代理使用:

将此课程添加到您的项目中:

+

并创建此函数以使用而不是原始连接:

public class ProxyTcpClient
{
    public TcpClient GetClient(string targetHost, int targetPort, string httpProxyHost, int httpProxyPort, string proxyUserName, string proxyPassword)
    {
        const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Instance;
        Uri proxyUri = new UriBuilder
        {
            Scheme = Uri.UriSchemeHttp,
            Host = httpProxyHost,
            Port = httpProxyPort
        }.Uri;
        Uri targetUri = new UriBuilder
        {
            Scheme = Uri.UriSchemeHttp,
            Host = targetHost,
            Port = targetPort
        }.Uri;

        WebProxy webProxy = new WebProxy(proxyUri, true);
        webProxy.Credentials = new NetworkCredential(proxyUserName, proxyPassword);
        WebRequest request = WebRequest.Create(targetUri);
        request.Proxy = webProxy;
        request.Method = "CONNECT";
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream responseStream = response.GetResponseStream();
        Type responseType = responseStream.GetType();
        PropertyInfo connectionProperty = responseType.GetProperty("Connection", Flags);
        var connection = connectionProperty.GetValue(responseStream, null);
        Type connectionType = connection.GetType();
        PropertyInfo networkStreamProperty = connectionType.GetProperty("NetworkStream", Flags);
        NetworkStream networkStream = (NetworkStream)networkStreamProperty.GetValue(connection, null);
        Type nsType = networkStream.GetType();
        PropertyInfo socketProperty = nsType.GetProperty("Socket", Flags);
        Socket socket = (Socket)socketProperty.GetValue(networkStream, null);

        return new TcpClient { Client = socket };
    }
}

最后连接到电报客户端:

public TcpClient _connect(string ip, int port)
{
    string proxyServer = "server ip";
    int proxyPort = port_number;
    string proxyUsername = "username";
    string proxyPassword = "password";
    ProxyTcpClient client = new ProxyTcpClient();
    return client.GetClient(ip, port, proxyServer, proxyPort, proxyUsername, proxyPassword);
}

答案 1 :(得分:0)

TcpClientConnectionHandler是一个委托!所以你必须定义一个函数,它返回一个TcpClient并将TELEGRAM地址和端口作为输入参数。 我用Socks代理做到了这一点并且它有效(注意,在我的情况下它是C#7和LOCAL函数):

var proxy = await _proxyProviderFactory.GetProxyProvider().GetProxyAsync().ConfigureAwait(false);
if (!string.IsNullOrEmpty(proxy))
{
    TcpClient TcpHandler(string address, int port)
    {
        var split = proxy.Split(':');
        var socksProxy = new Socks5ProxyClient(split[0], int.Parse(split[1]), split[2], split[3]);
        var tcpClient = socksProxy.CreateConnection(address, port);
        return tcpClient;
    }

    _client = new TelegramClient(_telegramApiId, _telegramApiHash, _sessionStore,handler:TcpHandler);