Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

HTTP proxy support in .NET does not actually support the lower level classes like TcpClient or Socket. But I want to connect a TCPServer (ip, port) through HTTP proxy that support 'CONNECT' command.

So I need to do the following steps:

  1. Connect to proxy.
  2. Send CONNECT Host:Port HTTP/1.1<CR><LF>
  3. Send <CR><LF>
  4. Wait for a line of response. If it contains HTTP/1.X 200, the connection is successful.
  5. Read further lines of response until receive an empty line.
  6. It's connected to the outside world through a proxy. Any data exchange as posssible with proxy.

Actually I do this without proxy

    TcpClient _client;
    NetworkStream _stream;

    public static async Task<bool> ConnectAsync(string hostname, int port)
    {
        _client = new TcpClient();
        await _client.ConnectAsync(hostname, port).ConfigureAwait(false);
        _stream = conn._client.GetStream();

        ..... Do some stuff

        // Connexion OK
        return true;
    }

How can use proxy and credentials before connecting TcpClient?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
600 views
Welcome To Ask or Share your Answers For Others

1 Answer

I find a solution base on .NET: Connecting a TcpClient through an HTTP proxy with authentication and Bypass the proxy using TcpClient

TcpClient _client;
NetworkStream _stream;

public TcpClient ProxyTcpClient(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 static async Task<bool> ConnectAsync(string hostname, int port)
{
        _client = ProxyTcpClient("IPTargetHost", 1234, "IPProxyHost", 5678, "Userproxy", "Userppwd");
        _stream = conn._client.GetStream();

        ..... Do some stuff

        // Connexion OK
        return true;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...