-
Как можно использовать стандартные функции работы с сокетами в Windows для прокси? В общем есть программы клиента и сервера, написанные на сокетах. Но между ними поставили проху. Как через него достучаться?
-
Прокси - это такая же программа-сервер, как и та которая у тебя "в общем есть". Поэтому для "достукивания" к ней используются те же самые функции - socket(), bind(), connect(), recv(), send() и т.д. и т.п.
-
Это понятно. Ну вот я с ней соединился. А дальше как за нее выйти к требуемому хосту? У сокета только одно соединение на один хост, а тут получается 2, одно на прокси, второе - целевое (конечное).
-
> А дальше как
А дальше все зависит от протокола, который поддерживает тот прокси, к которому ты обращаешься. Это м.б. и HTTP, и HTTPS, и SOCKS4/4a/5, и .. да мало ли разных протоколов и соответствующих прокси ..
-
> У сокета только одно соединение на один хост, а тут получается > 2, одно на прокси, второе - целевое (конечное).
И тут тоже получается одно - к прокси-серверу. А тот уже, по просьбе клиента на языке соответствующего прокси-протокола, соединяется с целевым сервером. На то он и прокси (от англ. proxy - посредник), чтобы быть посредником в коммуникациях между клиентами и серверами.
-
Это мне понятно, но задача в другом. Есть уже написанный сервер и разные клиенты, которые работают используя WinSock, типа TCustomIpClient. И у них только свойство LocalHost (Specifies the name of the local system) и RemoteHost (Specifies the name of the remote system). Так говорит хелп. На это уровне нет понятия протокола (HTTP, и HTTPS, и SOCKS4/4a/5). Т.е. если у прокси стоит не прорачное проксирование , то клиент вообще не может никуда выйти, прокси его не пускает. Тем более мне непонятно как быть в случае авторизации на прокси, т.к. на это уровне нет понятия авторизации. Или я вообще ничего не понимаю?!
-
> Есть уже написанный сервер
И пусть он себе есть - его этот вопрос совершенно не касается.
> На это уровне нет понятия протокола (HTTP, и HTTPS, и SOCKS4/4a/5)
Совершенно верно.
> и разные клиенты
Они на каком языке с сервером разговаривают ? Какой-то стандартный прикладной протокол используется или самописный ?
-
> DmitryA (05.11.09 12:49) [2]
Обычно никак, как правило в случае прокси, никуда не выпускают, это могила, последний вздох, дальше работает только прокси и результат возвращается клиенту. Но бессмысленно говорить о прокси, надо говорить об конкретном прокси и смотреть его протокол.
-
Иногда прокси называют сессионную систему авторизации. Когда выпуск во вне производится по паролю на сессию. Это просто выключатель, если включено, то пакеты идут дальше, если нет, то умирают.
-
Используется самописный протокол.
-
Т.е. получается, без вариантов? Это как-то грустно ;(... Но работают же как-то другие системы или у нас в мире настолько все стало единообразно, что только стандартные системы рабоают?
-
> DmitryA (05.11.2009 15:42:09) [9]
Самописный протокол требует и самописного подключения к прокси.
-
Вот это-то и понятно. Но как это сделать имея только класс типа TCustomIpClient?
-
> DmitryA (05.11.2009 16:15:12) [12]
Делать в соответствии с протоколом, который должен быть хорошо документирован. Но это паршивый путь, включать в программу и не только прямую поддержку таких протоколов, проблем будет очень много. Реализация протоколов может быть самописной, но сами протоколы должны быть стандартными.
-
Все дело в том, что работа через сокеты это на уровень ниже всяких протоколов. Это означает также и полное отсутсвие авторизации в том числе. Т.е. соединение между клиентом и сервером либо физически установлено, либо нет. И сдесь нет понятия кого-то еще (прокси), который требует авторизации по какому-то формату в зависимости от типа протокола. Я могу ошибаться, прокси работает на 7 уровне (прикладной), а сокеты на 4 (транспортный). Поэтому мне непонятно как процесс на уровне 4 может общаться с процессом на уровне 7?
-
> DmitryA (05.11.2009 16:50:14) [14]
Это так и согласно вопросу, придется реализовывать и 7 уровень, тоже
-
Так как его реализовать, если соединение по нестандартному (относительно существующих протоколов) порту? Как прокси знает, что на этом порте с ним будут общаться по известному протоколу? Например, порт 4128, а протокол HTTP? И нельзя привязываться жестко к какому-то прокси, т.к. их может быть несколько и разных.
-
> DmitryA (05.11.09 15:49) [10] > Т.е. получается, без вариантов? Это как-то грустно ;(... > Но работают же как-то другие системы или у нас в мире настолько > все стало единообразно, что только стандартные системы рабоают? >
Ну как же без вариантов? Пишешь собственный прокси, в котором уже работаешь с чужим прокси.
-
> Как прокси знает, что на этом порте с ним будут общаться > по известному протоколу?
Никак. Прокси не будет обслуживать клиентов, разговаривающих с ним на неизвестном ему языке.
> порт 4128, а протокол HTTP
А вот на это существуют прокси, поддерживающие прозрачное проксирование, и маскарадные NAPT.
> нельзя привязываться жестко к какому-то прокси, т.к. их > может быть несколько и разных
Без переделки/доработки клиента либо создания доп.софта, работающего в паре с клиентом прозрачно для него, задача не решаема
-
> Например, порт 4128, а протокол HTTP?
Это уже прозрачный прокси, ему ничего не надо знать, точнее клиенту ничего не надо знать.
-
проще всего использовать между клиентом и сервером http протокол, а транспорт сделать на xmlhttprequest. если браузер у юзера настроен, то все случится само собой
-
Проще использовать туннель предназначенный в протоколе НТТР.
Типа
CONNECT <имясервера>:<номер порта> HTTP/1.1 Host: <имясервера>:<номер порта>
Ждем
HTTP/1.1 200 OK
И можем слать что угодно... :)
-
это если он есть на прокси
-
Uses: WinInet;
procedure ChangeProxy(aProxy: string);
var
PIInfo: PInternetProxyInfo;
begin
New(PIInfo);
PIInfo^.dwAccessType := INTERNET_OPEN_TYPE_PROXY;
PIInfo^.lpszProxy := PChar(aProxy);
PIInfo^.lpszProxyBypass := PChar('');
UrlMkSetSessionOption(INTERNET_OPTION_PROXY, piinfo,
SizeOf(Internet_Proxy_Info), 0);
Dispose(PIInfo);
end;
function GetUrl(const Url: string): string;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1024] of char;
BytesRead: cardinal;
begin
Result := '';
NetHandle := InternetOpen(sfk_n, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(NetHandle) then
begin
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
begin
FillChar(Buffer, SizeOf(Buffer), 0);
repeat
Result := Result + Buffer;
FillChar(Buffer, SizeOf(Buffer), 0);
InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
until BytesRead = 0;
InternetCloseHandle(UrlHandle);
end
else
begin
raise Exception.CreateFmt('Cannot open URL %s', [Url]);
end;
InternetCloseHandle(NetHandle);
end
else
raise Exception.Create('Unable to initialize Wininet');
end;
(Без авторизации!)
|