Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.09.23;
Скачать: CL | DM;

Вниз

Смесь бульдога с носорогом: моя версия :))   Найти похожие ветки 

 
savva ©   (2002-07-19 11:14) [0]

Короче дела такие... подробности того, как я пытаюсь открыть сокет..

const
// В заголовке необходимы некоторые данные
HTTP_Data =
"Content-Type: application/x-www-form-urlencoded"#10+
"User-Agent: Chat Client By Savva (savva@nm.ru)"#10+
"Host: savva.ru"#10+
"Connection: Keep-Alive: on"#10;

....


Соединение открываю так:

function TForm1.DoConnect(user,msg : string): boolean;
begin
Content:= msg + #10;
// Вычисляем длину содержимого
Content:= "Content-Length: "+IntToStr(Length(Content))+#10+#10+Content;
if chUseProxy.Checked then begin
{-- Начало прокси ---}
ClientSocket1.Host := edProxyServer.Text;;
ClientSocket1.Port := StrToIntDef( edProxyPort.text,3128);
HTTP_POST := " http://"+edWebServer.Text+":"+edWebPort.text+" "+
user+""#10;
{--- Конец прокси ---}
end else begin
{--- Начало соединения напрямую --- }
ClientSocket1.Host := edWebServer.Text;
ClientSocket1.Port := StrToIntDef( edWebPort.text,3000);
HTTP_POST := user+#10;
{--- Конец соединения напрямую ---}
end;
// Соединяем заголовок
HTTP_Post := HTTP_Post + HTTP_Data;

// открываем соединение
ClientSocket1.Active:=true;
mess_str:=HTTP_POST+Content;
result:=true;
end;

...

procedure TForm1.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
begin
// Постим данные при коннекте
Socket.SendText(mess_str);
mess_str:="";
end;

то есть фактически после этого мы имеем открытый транспортный канал, но дальнейшие телодвижения типа Socket.SendText("что нибудь"); не приводят ни к какому результату. Причем со стороны сервера такие вещи проходят - клиент получает сообщения и прекрасно их может читать :)

тут мне напрашивается вопрос - а не надо ли перед посылкой сообщения от клиента серверу к тексту припысать какую либо еще информацию? Может прокси сервер прикрывает соединение (хотя это наврядли - сообщение-то от сервера приходят) !?!


 
Digitman ©   (2002-07-19 11:27) [1]

Т.е., факт успешного установления коннекта ты фиксируешь по событию OnWrite(), и в этом же событии передаешь первый запрос к серверу. Так ?


 
savva ©   (2002-07-19 11:41) [2]

ага


 
savva ©   (2002-07-19 11:42) [3]

ведь событие OnConnect возникает при присоединении с прокси серверу..


 
Digitman ©   (2002-07-19 11:57) [4]

А OnWrite(), по-твоему, чем отличается от OnConnect() ?

OnWrite() следует сразу за OnConnect() и говорит лишь о доступности буфера гнезда к записи в него данных, которые ты собираешься передавать.

Собственно, криминала здесь нет никакого, можно и OnWrite() пользоваться как фактом коннекта, но оно может возникать и неоднократно. Как минимум, это ты не учитываешь, imho. Т.е. в какой-то момент времени в очередном событии OnWrite() ты пошлешь серверу вовсе не то, что он ожидает в соответствии с протоколом http , и сервер просто "заткнется", не понимая тебя. Что, похоже, у тебя и происходит ...

Не исключена ситуация с потенциальным нарушением протокола инф.обмена.

Убедись, что OnWrite() вызывается неоднократно.


 
Digitman ©   (2002-07-19 12:07) [5]

Вот фрагмент хэлпа с описанием к сетевому событию FD_READ :

The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with connect/WSAConnect (after FD_CONNECT, if also registered) or accepted with accept/WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will be notified that sends are again possible with an FD_WRITE message.


 
savva ©   (2002-07-19 12:09) [6]

при использовании SendText - точка останова сработала 1 раз - при коннекте..
а когда возникает событие OnWrite, при каких условиях?


 
Digitman ©   (2002-07-19 12:09) [7]

Пардон, ошибочка :
... фрагмент хэлпа с описанием к сетевому событию FD_WRITE


 
savva ©   (2002-07-19 12:10) [8]

ясно..


 
savva ©   (2002-07-19 12:21) [9]

причем посылка заголовку прокси серверу в момент коннекта (OnConneсted) не меняет картины...


 
Digitman ©   (2002-07-19 12:21) [10]

клиент-то у тебя ctNonBlocking или ctBlocking ? Это важно с т.з. логики возбуждения событий


 
savva ©   (2002-07-19 12:24) [11]

ctNonBlocking


 
Digitman ©   (2002-07-19 12:30) [12]

Значит, все идет к тому, что нарушен-таки протокол логического инф.обмена ... сервер получает клиентский исх.поток, не может его интерпретировать его содержимое как корректное с т.з. протокола и попросту игнорирует его, не отвечая клиенту ... и вот отсутствие ответа ты и воспринимаешь якобы как "глюки" в транспорте ...

Убедиться каким-либо образом в факте события FD_READ на серверной стороне ты в состоянии ?


 
Digitman ©   (2002-07-19 12:33) [13]

т.е. текст в mess_str на момент передачи - некорректен, видимо.



 
Wonder ©   (2002-07-19 12:34) [14]

Извиняюсь за вмешательство :), а прокси-то какой? HTTP?


 
savva ©   (2002-07-19 12:35) [15]

>сервер получает клиентский исх.поток
речь идет я так понял про прокси сервер?

что значит в состоянии?:)) осталось выбрать "образ"...
При возникновении события OnRead на сервере строка перво-наперво сохраняется в лог-файл... (Пока речь идет тока строках..) Если можно вклинится раньше такого способа - то я не знаю как.


 
savva ©   (2002-07-19 12:39) [16]

>Wonder © (19.07.02 12:34)
ага..
любому вмешательству я тока рад :))
>Digitman © (19.07.02 12:33)
то есть мы приходим к выводу что перед отсылкой необходимо к тексту сообщения приплюсоввывать что-то.. такой вариант тоже не проходит - прибавляю тоже самое что и при коннекте..


 
Digitman ©   (2002-07-19 12:41) [17]

Пока речь идет о прокси : он первый в цепочке передачи получает кл.поток, анализирует, фильтрует и перенаправляет ...

Упс ... <Wonder> верную ведь мысль подал : с прокси самим все в порядке ? http держит он ?


 
savva ©   (2002-07-19 12:44) [18]

именно http он и держит (поддерживает..) через него IE работает...
прокси - WinRoute..(если это важно :))


 
Wonder ©   (2002-07-19 12:45) [19]

Так.
Насколько я понимаю http-прокси работают следующим образом: любой трафик со стороны клиента обрабатывается прокси в соответствии со стандартом http. Ни о каком транспортном канале до веб-сервера не может идти речи, потому как прокси работает на уровне протокола http (на то он и http-прокси :) А вот со стороны веб-сервера прокси-серверу уже до балды соответствие трафика какому-либо протоколу высокого уровня. Потому как это уже браузер клиента отслеживает.


 
Digitman ©   (2002-07-19 12:46) [20]

"приплюсоввывать что-то" или наоборот убрать лишнее - здесь уже я тебе вряд ли что-то подскажу ... вступает в силу ПИО с прокси-сервером, "держащим" http...

разумеется, если прокси "споткнулся" на твоем заголовке запроса, никакой речи о трансляции его целевому узлу и речи быть не может ...


 
Digitman ©   (2002-07-19 12:49) [21]

"приплюсоввывать что-то" или наоборот убрать лишнее - здесь уже я тебе вряд ли что-то подскажу ... вступает в силу ПИО с прокси-сервером, "держащим" http...

разумеется, если прокси "споткнулся" на твоем заголовке запроса, никакой речи о трансляции его целевому узлу и речи быть не может ...


спроси у Володи (<Wonder>) на тему ПИО с http-прокси - он гораздо "круче" меня владеет этими тонкостями


 
savva ©   (2002-07-19 12:50) [22]

>Wonder © (19.07.02 12:45)
я тоже так думал..
но тут тогда появляется не понятка почему функция


function TForm1.Send_Text( msg : string): boolean;
begin
Content:= msg + #10;
// Вычисляем длину содержимого
Content:= "Content-Length: "+IntToStr(Length(Content))+#10+#10+Content;
if chUseProxy.Checked then begin
{-- Начало прокси ---}
ClientSocket1.Host := edProxyServer.Text;;
ClientSocket1.Port := StrToIntDef( edProxyPort.text,3128);
HTTP_POST := " http://"+edWebServer.Text+":"+edWebPort.text+" "+
{user name}nickname+""#10;
{--- Конец прокси ---}
end else begin
{--- Начало соединения напрямую --- }
ClientSocket1.Host := edWebServer.Text;
ClientSocket1.Port := StrToIntDef( edWebPort.text,3000);
{--- Конец соединения напрямую ---}
end;
// Соединяем заголовок
HTTP_POST :=HTTP_Post+#$D#$A+ msg+#10;
HTTP_Post := HTTP_Post + HTTP_Data;

mess_str:=HTTP_POST+Content;


sckt.SendText(mess_str);
result:=true;
end;
не имеет желаемого результата...


 
Digitman ©   (2002-07-19 12:53) [23]

Так, ну а "Журнал http" в WinRoute что показывает на эту тему ? Или это сложно - поиметь такую инфу ?


 
savva ©   (2002-07-19 12:56) [24]

>Digitman © (19.07.02 12:53)
ща


 
Wonder ©   (2002-07-19 12:59) [25]

Как я делал в таких случаях дабы не обременять себя вычитыванием RFC и составлением правильных http-пакетов :)))

- Берем снифер
- Браузером отправляем данные через форму по какому-либо адресу (например, постинг сюда)
- Смотрим http-пакет
- Отправляем твоей программой
- Смотрим http-пакет
- Сравниваем оба пакета на предмет различий


 
savva ©   (2002-07-19 13:02) [26]

>Wonder © (19.07.02 12:59)
подход верен.. но почему один и тот же пакет не проходит 2 раза..


 
Wonder ©   (2002-07-19 13:04) [27]

Непонял. Ты ж говоришь, что от клиента к серверу вообще ничего не идет. Какие два раза?


 
Digitman ©   (2002-07-19 13:08) [28]

Получается, что первое сообщение имеет корректный формат (и Web-сервер, обработав, вернул тебе результат) , а последующие - некорректный.

Ты хочешь сказать, что "напрямую" (без прокси) обмен идет успешно ?


 
Digitman ©   (2002-07-19 13:17) [29]

Так, стоп. Ты уже двоих запутал) ...

О факте установления транспортного канала говорит как минимум событие OnConnect(), никакие логические данные, передаваемые в SendText() в OnWrite() или еще где-то к транспорту как таковому отношения не имеют - он либо есть либо его нет ...

Вот теперь скажи - есть ли реакция Web-сервера на самый 1-й SendText() ?


 
savva ©   (2002-07-19 13:18) [30]

первый раз проходит - при коннекте DoConnect функция а второй : Send_Text - их содержание практически идентично.. при коннекте сервер получает:
/ savva

Content-Type: application/x-www-form-urlencoded
User-Agent: Chat Client By Savva (savva@nm.ru)
Host: savva.ru
Content-Length: 27
Connection: close

а далше тихо как в гробу..

лог:
[19/Jul/2002 13:10:02] Packet filter: ACL 2:0 Intel(R) PRO Adapter: permit packet out id=36386 : TCP 192.168.0.XX:3627 -> 192.168.0.XX:3128

[19/Jul/2002 13:10:02] Packet filter: ACL 2:0 Intel(R) PRO Adapter: permit packet out id=36388 : TCP 192.168.0.XX:3627 -> 192.168.0.XX:3128

[19/Jul/2002 13:10:02] Packet filter: ACL 2:0 Intel(R) PRO Adapter: permit packet out id=36389 : TCP 192.168.0.XX:3627 -> 192.168.0.XX:3128

[19/Jul/2002 13:10:02] Packet filter: ACL 2:0 Intel(R) PRO Adapter: permit packet out id=36391 : TCP 192.168.0.XX:3627 -> 192.168.0.XX:3128


дальнейшие посылы SendText не вызывают у прокси никакх изменений..


 
savva ©   (2002-07-19 13:21) [31]

то что я запутал - это я понял :)))
поясняю ситуацию :))
есть сервер слушает 1 порт.. к примеру 3000. он в интернет лезет без прокси..
есть клиент, выходящий через прокси..

все остальное я уже говорил :))) по порядку :))))


 
savva ©   (2002-07-19 13:22) [32]

>Digitman © (19.07.02 13:17)
да... он получает см.выше


 
Wonder ©   (2002-07-19 13:31) [33]

Например, в HTTP_Data вот это вот:
"Connection: Keep-Alive: on"#10;
ты откуда взял?


 
Digitman ©   (2002-07-19 13:35) [34]

"есть сервер слушает 1 порт"
один порт ? или первый ? ну почему так трудно написать недвусмысленно-то ?

Какой сервер ? Web-сервер ? Зачем ему куда-то "лезть" ? Клиент в Интернет "лезет" к Web-серверу через цепочку прокси (твой WinRoute да еще, может быть - прокси провайдера) ...

Вот это поясни ...


 
Digitman ©   (2002-07-19 13:38) [35]

и вот это еще :

Connection: close

как это сочетается с твоим

Connection: Keep-Alive: on

?


 
savva ©   (2002-07-19 13:40) [36]

>Wonder © (19.07.02 13:31)
это совет нашего веб-мастера-админа :)) если честно, то я с трудом представляю зачем это, но если ему верить, то так прокси должен оставлять соединение :)))

>Digitman © (19.07.02 13:35)
прошу прощения.
один порт. конечно сервер никуда не лезет :)) просто я сказал это в такой форме чтоб было понятно что ему ничего не мешает видеть прокси сервер клиента напрямую... (как бы опять не запутать..)


 
savva ©   (2002-07-19 13:41) [37]

>Digitman © (19.07.02 13:38)
а вот это уже выше моих знаний...
"Connection: close" - это приходит моему серверу от прокси

"Connection: Keep-Alive: on" - это посылает коиент прокси серверу..


 
savva ©   (2002-07-19 13:46) [38]

в поддержку того, что соединение все таки существует - прокси сервер закрывает через 10 минут (время простоя) соединение...
вполне возвможно что это тока соединение с прокси сервером..


 
Digitman ©   (2002-07-19 13:51) [39]

Блин, ничего не пойму)

Что есть "мой сервер" ? Мы говорим об отладке HttpChat-клиента или некоего (не твоего и не в твоей ЛВС) Web-сервера, на котором размещен скрипт твоего же чат-движка?


 
savva ©   (2002-07-19 13:57) [40]

вот где собака порылась:)))
мы говорим о Chat-клиенте на протоколе HTTP и сервере не моей сети (но это признак не обязателен, в принципе к программе серверу будет доступ и из локальной сети). Исполнение сервера - не скрипт. Win32 приложение...

Грубо говоря - чат из примеров Делфи по сокетам, тока расширенный до возможности работать через HTTP proxy


 
Wonder ©   (2002-07-19 13:58) [41]

Так вот скажи своему админу, что этого в стандарте нету :)

The following describes the original HTTP/1.0 form of persistent
connections.

When it connects to an origin server, an HTTP client MAY send the Keep-Alive connection-token in addition to the Persist connection-token:

Connection: Keep-Alive

An HTTP/1.0 server would then respond with the Keep-Alive connection token and the client may proceed with an HTTP/1.0 (or Keep-Alive)persistent connection.

An HTTP/1.1 server may also establish persistent connections with HTTP/1.0 clients upon receipt of a Keep-Alive connection token.
However, a persistent connection with an HTTP/1.0 client cannot make use of the chunked transfer-coding, and therefore MUST use a Content-Length for marking the ending boundary of each message.

A client MUST NOT send the Keep-Alive connection token to a proxy server as HTTP/1.0 proxy servers do not obey the rules of HTTP/1.1 for parsing the Connection header field.


 
Digitman ©   (2002-07-19 14:10) [42]

Итак,

WinRoute - на одной из машин в твоей же ЛВС (возможно, на той же машине, которая является сервером доступа к провайдеру).

Чат-клиент (приложение, использующее TClientSocket) - в той же ЛВС, коннект к чат-серверу может осуществлять как непосредственно через интерфейс провайдера, так и через WinRoute

Чат-сервер - Win32-париложение, предоставляющее Web-сервис на 3000-м порту где-то в глоб.сети на некоем хосте


Так ?


 
savva ©   (2002-07-19 14:14) [43]

аг :))


 
savva ©   (2002-07-19 14:16) [44]

не ясно я значит разъяснял...


 
Digitman ©   (2002-07-19 14:17) [45]

>savva
Видимо, дальше можно и не продолжать)

Володя тебе привел конкретный аргумент по использованию токена Keep Alive

В ответ на несуразицу с Keep Alive ты и получаешь от своего WinRoute "Connection: close"


 
savva ©   (2002-07-19 14:17) [46]

даа...


Владимир и Сергей, спасибо Вам за проявленное участие к моему вопросу. Но вопрос остается не решенным, я скорее всего не смогу более принимать учатие в беседе на протяжение отпуска. Точнее сказать, эпизодично у меня будет возможность в инет выйти, но скорее всего эта ветка уползет вниз...

Проблема осталась, но времени ее решать пока нету...

PS. Если вдруг по какой либо случайности найдется один из вариантов решение - дайте мне знать по e-mail... Если конечно трудно не будет...

PSS. ща вынужден убежать, но в понедельник постараюсь заглянуть...


 
savva ©   (2002-07-19 14:21) [47]

допустим...
но есть ли пример заголовка такой чтобы прокси не закрывал соединение? (наглость второе счастье..)


 
Digitman ©   (2002-07-19 14:22) [48]

получается, что чат-сервер использует HTTP/1.0 и в ответ на Keep Alive попросту закрывает коннект по собственной инициативе.

О чем тебе WinRoute и сообщает в логе.


 
Digitman ©   (2002-07-19 14:28) [49]

Все из той же "оперы" - нарушение или игнорирование ПИО )))

Так что TCP-транспорт у твоего клиента ни при чем здесь - работает как положено.

Кстати, подожди ... )

Вот есть момент один .. когда-нить наступишь на грабли :

// открываем соединение
ClientSocket1.Active:=true;
mess_str:=HTTP_POST+Content //(***)

Что будет, если вот это

procedure TForm1.ClientSocket1Write(Sender: TObject;
Socket: TCustomWinSocket);
begin
// Постим данные при коннекте
Socket.SendText(mess_str);
mess_str:="";
end;

выполнится раньше, чем (***) ?

На основании чего ты уверен, что ожидаемая тобой последовательность никогда не нарушится ?


 
savva ©   (2002-07-19 14:31) [50]

:)) уже поменял... были сомнения, но ошибок не было в работе в ЛВС


 
Digitman ©   (2002-07-19 14:38) [51]

для ЛВС эти "грабли" - по барабану) ... это твой клиент будет на них наступать регулярно : если нечетко представляешь себе последовательность событий, клиент будет получать дисконнект по "непонятной" причине, если вообще не "упадет" в самый критичный момент ... а грамотно написанному чат-серверу на проблемы твоего клиента начхать : он либо молчать будет либо отключать кл.транспорт, чуть что некорректно или невовремя его клиент спросит ...


 
savva ©   (2002-07-19 14:41) [52]

как такового дисконекта от прокси сервера нет. Я так понимаю, что если они (прокси сервер и клиент) находятся в одной сети, то при закрытии соединения прокси сервером должно генерироваться событие дисконнекта?


 
savva ©   (2002-07-19 14:46) [53]

все.. ладно, я убег...

всем удачи!



Страницы: 1 2 вся ветка

Текущий архив: 2002.09.23;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.017 c
14-73871
Shrek
2002-08-28 17:41
2002.09.23
SoftIce


7-73905
Sergey_
2002-07-15 13:59
2002.09.23
Здравствуйте. Как можно программно выключить компьютер.


14-73882
Lamer86
2002-08-29 16:05
2002.09.23
Народ, помогите с файлом


1-73715
liho26
2002-09-11 06:43
2002.09.23
версию программы в Form1.Caption. Как это сделать?


1-73671
Shoo
2002-09-13 09:42
2002.09.23
Одноразовая прога