Вверх ↑
Ответов: 2125
Рейтинг: 159
#1: 2008-05-21 21:46:10 ЛС | профиль | цитата
Byuik писал(а):
Почему я должен доказывать людям которые ничего не хотят слышать , что их компонент в среде Delphi глючит ?

Давай определимся: глючит у тебя, возможно ещё у кого-то.
А вот я у себя глюков не замечал. Вопрос: как я могу поймать глюк, которого у меня нет?

------------ Дoбавленo:

Byuik, мне сначала было лень анализировать, как работает твоя схема, но ты вынудил меня сделать это своими заявлениями.

Первое, что бросается в глаза: необоснованное наличие целых трёх компонентов Thread, пользоваться ими надо аккуратно, и всегда иметь ввиду, что возможен одновременный доступ со стороны нескольких из них.
В данном случае было не особо важно, т.к. обе цепочки, в которых присутствует Thread запускались последними, после onRead сокета. Однако исключать то, что следующий onRead придёт раньше, чем отработает Thread, тоже нельзя.

Второе, насчёт onRead: в схеме данные сначала записываются в StrList, а потом уже оттуда передаются на отправку, причём всегда. С текстовыми данными так ещё можно поступить, а вот с бинарными (картинки) - не советую. Нет никакой гарантии, что StrList не уберёт пару символов перевода строки или не обрежет "строки" после символа (если так можно выразиться о бинарных данных, разделённых символами
).

Третье, опять про onRead: было бы наивным полагать, что весь ответ от браузера ты получишь в одном onRead. Это ты учёл - молодец. Но как? Что произойдёт, когда придёт второй onRead?
1. снова анализ заголовка. Зачем? А если всё таки встретится GET или POST - произведёшь модификацию данных? Но ладно, это маловероятно.
2. соединение активно, опять запускаем Thread (вероятно, чтобы освободить от пересылки данных основной Thread), однако предыдущая посылка данных могла ещё не завершиться (multithread блин) - опять наплевали на это.
3. что у нас там после хаба? Опять doOpen TCP_Connection! Не поленился, заглянул в код компонента:
procedure THITCP_Client._work_doOpen;
var p:word;
h:string;
begin
if not Assigned(Sock) then Attach(TSocket.Create); // сокет уже есть - ладно, проглотили
P := ReadInteger(_Data,_data_Port,_prop_Port);
H := ReadString(_Data,_data_IP,_prop_IP);
Sock.StartClient(p,h); // но тут мы сделаем ему снова StartClient. Что произойдёт?
end;
А произойдет следующее:

procedure TSocket.StartClient;
var addr:sockaddr_in;
begin
CreateWindow;
FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP); // открываем ещё один сокет! про старый забыли начисто, хотя именно туда надо было посылать данные.
addr.sin_family := AF_INET;
addr.sin_port := htons(Port);
addr.sin_addr.S_addr := inet_addr(PChar(Host));
if connect(FSocket,addr,sizeof(addr)) <> 0 then // опять соединяемся с сервером
begin
closesocket(FSocket);
FSocket := 0;
end
else
begin
BeginRead; // ещё один новый Thread, теперь уже для чтения из сокета. Мало нам существующих Thread? Между прочим, предыдущий так и продолжает читать из первого сокета.
if Assigned(onConnect) then
onConnect(self);
end;
end;

Вобщем, как это всё работает - непонятно. Основная проблема - пункт 3. Учитывая, что браузер иногда использует то-же самое соединение для посылки следующего запроса.
Или всё-таки пункт 2? Незаконченная Thread-ом пересылка обрывается новым запросом...
------------ Дoбавленo:

Ну что, Byuik, допёк ты меня
Действительно есть баг в TCP.pas. Ставлю тебе плюс, за настойчивость.
В очередной раз убедился, что на локальном компьютере и в локальной сети - две большие разницы.
Дома смоделировать ситуацию, как ты понимаешь, не получалось.
Все работающие с сокетами - качаем обновление http://hiasm.googlecode.com/svn/elements/delphi/code/TCP.pas

Как всегда, ошибка была там, где её меньше всего искали - на видном месте.
карма: 1

1
Голосовали:Konst