Нам нужно подключить наш tcp-сервер и установить tcp-соединение за прокси-сервером (большинство брандмауэров блокируют наше прямое tcp-соединение с определенным портом).
Итак, мы внедрили прокси-сервер Apache http и подключили tcp, используя HTTP CONNECT METHOD через наш прокси-сервер http.
Итак, нам нужно сделать следующие шаги:
- Подключение к прокси.
- Отправить
CONNECT Host:Port HTTP/1.1<CR><LF>
- Отправить
<CR><LF>
Ждите ответной строки. Если он содержит HTTP/1.X 200
, соединение установлено
Читайте дальнейшие строки ответа, пока не получите пустую строку.
- Это связано с внешним миром через прокси
Ниже я нашел два кода, написанных кем-то для этого.
Мой вопрос : Каков наилучший подход для создания TCP-соединения за прокси-сервером. И каким способом я должен использовать Webrequest или через TCP-сокет?
public static class HttpProxy
{
public static TcpClient connectViaHTTPProxyMethod1(
string targetHost,
int targetPort,
string httpProxyHost,
int httpProxyPort,
string proxyUserName,
string proxyPassword)
{
UriBuilder uriBuilder = null;
Uri proxyUri = null;
if (httpProxyHost != "")
{
uriBuilder = new UriBuilder
{
Scheme = Uri.UriSchemeHttp,
Host = httpProxyHost,
Port = httpProxyPort
};
proxyUri = uriBuilder.Uri;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
"http://" + targetHost + ":" + targetPort);
//request.Timeout = 1000 * 60 * 60;
request.KeepAlive = false;
var webProxy = new WebProxy(proxyUri);
if (httpProxyHost != "")
request.Proxy = webProxy;
request.Method = "CONNECT";
var credentials = new NetworkCredential(
proxyUserName, proxyPassword);
if (proxyUserName != "")
webProxy.Credentials = credentials;
var response = request.GetResponse();
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 };
}
public static TcpClient connectViaHTTPProxyMethod2(string targetHost, int targetPort, string httpProxyHost, int httpProxyPort, string proxyUserName, string proxyPassword)
{
byte[] buffer = new byte[2048];
int bytes;
// Connect socket
// Dnt know how to implement proxyUserName proxyPassword
TcpClient client = new TcpClient(httpProxyHost, httpProxyPort);
NetworkStream stream = client.GetStream();
// Establish Tcp tunnel
byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:{1} HTTP/1.1\r\nHost:{0}\r\n\r\n", targetHost, targetPort));
stream.Write(tunnelRequest, 0, tunnelRequest.Length);
stream.Flush();
// Read response to CONNECT request
bytes = stream.Read(buffer, 0, buffer.Length);
return client;
}
}