Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прочитать одну строку с помощью TcpClient, именно ОДНУ, и не больше 
V
    Опции темы
Ibragim
Дата 25.1.2007, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Вечер добрый. 
Вот участок кода, который, как я всегда считал, принимает первую строку ответа сервера ya.ru.

Код

      st := TTCPClient.Create(nil);
      st.RemoteHost := 'ya.ru';
      st.RemotePort := '80';
      s := '';

        if not st.Connect then ECannotConnect.Create('Error');
        st.Sendln('GET /' + ' HTTP/1.1');
        st.Sendln('User-Agent: Opera/9.00 (Windows NT 5.1; U; en)');
        st.Sendln('Host: ' + 'ya.ru');
        st.Sendln('Accept-Language: en');
        st.Sendln('Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1');
        st.Sendln('');
        s := st.Receiveln;
        st.Disconnect;




Однако посмотрел сниффером и увидел следующую картину:

GET / HTTP/1.1
User-Agent: Opera/9.00 (Windows NT 5.1; U; en)
Host: ya.ru
Accept-Language: en
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1

HTTP/1.0 200 OK
Content-Type: text/html; charset=windows-1251
ETag: "-665585201"
Accept-Ranges: bytes
Last-Modified: Mon, 15 Jan 2007 14:07:39 GMT
Content-Length: 2377
Date: Thu, 25 Jan 2007 20:46:57 GMT
Server: httpd
Age: 17
Connection: close

<html>
<head>
<title>.ndex</title>
<link rel="SHORTCUT ICON" href="/favicon.ico" />
<base target="_top" />
<style type="text/css">
и так далее...


То есть по сети в действительности передается ВЕСЬ сайт, что создает совершенно мне не нужную нагрузку на канал. Дело, очевидно, в свойствах сокетов, в которых я не силен. Не подскажет ли уважаемое сообщество, как не тратить трафик и "заставить" обрывать соединение после получения первой строки.
Заранее спасибо.

PS Приведенный пример для компонент TTcpClient из sockets.pas, но если поставить TIdTcpClient - картина точно та же.

Это сообщение отредактировал(а) Ibragim - 25.1.2007, 23:55
PM MAIL   Вверх
Snowy
Дата 26.1.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Код

  s := st.Receiveln(#$A);

PM MAIL   Вверх
Ibragim
Дата 26.1.2007, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Не помогает. Вот весь код, на форме одна кнопка. Може еще кто чего насоветует?

Код

ECannotConnect = class(Exception);

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  st: TTcpClient;
begin
  st := TTCPClient.Create(nil);
  st.RemoteHost := 'ya.ru';
  st.RemotePort := '80';

  if not st.Connect then ECannotConnect.Create('Error');
  st.Sendln('GET /' + ' HTTP/1.1');
  st.Sendln('User-Agent: Opera/9.00 (Windows NT 5.1; U; en)');
  st.Sendln('Host: ' + 'ya.ru');
  st.Sendln('Accept-Language: en');
  st.Sendln('Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1');
  st.Sendln('');
  s := st.Receiveln(#$A);
  st.Disconnect;
end;


PM MAIL   Вверх
Snowy
Дата 26.1.2007, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Давай по порядку.
Как ты себе представляешь чтение строки из сокета?
Неправильно представляешь.
Из сокета читается буфер. Потом в нём ищется символ конца строки.
ReceiveLn принимает 512 байт и ищет там символ конца строки.
Это число можно снизить:
Код

  SetLength(s, 32);
  st.ReceiveBuf(s[1], 32);
  st.Disconnect;
  if Pos(#$D, s) > 0 then s := Copy(s, 1, pos(#$D, s));
В примере читается буфер в 32 байта.

Теперь по логике вещей будет принято только 32 байта.
Неверно!
Сервер шлёт нам поток данных. И винда этот поток принимает в буфер сокета.
Даже, если мы не прочитаем ни одного байта, всё равно приём идёт до тех пор, пока мы не разорвём соединение, либо пока буфер приёма не будет заполнен полностью.
Чем быстрее мы разорвём соединение, тем меньше примет винда.
Но, можешь мне поверить, на высокоскоростном канале она успеет принять всё smile
Если только файл не превышает размер буфера... Если мне не изменяет память, то он обычно может быть от 8 до 64кб
И помешать этому никак не получится. Разве что писать на уровне драйвера и рубить приём физически.
PM MAIL   Вверх
Ibragim
Дата 26.1.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Спасибо большое за объяснение.
Гуд, именно это я и подозревал когда писал в первом посте "Дело, очевидно, в свойствах сокетов".

А такой вопрос тогда, исходя из объяснения получается, что в любом случае принимается из сети не больше буффера сокета, как в Вашем, так и в моем примере? 

Если это так, то в принципе это уже приемлемый результат - все равно загрузка канала должна существенно упасть по сравнению с IdHttp.Get().

Я правильно понял пояснение?
PM MAIL   Вверх
Snowy
Дата 27.1.2007, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Можно попробовать также IdHTTP.Head

Принимается из сети не больше буфера сокета + то, что мы из этого буфера прочитали, т.е. наши 32 байта.
Мы же их из буфера забрали - место в буфере освободилось.
В остальном всё верно. Для больших страниц и файлов.
Для маленьких и обычных результат идентичен - они меньше буфера.
PM MAIL   Вверх
Ibragim
Дата 30.1.2007, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Спасибо большое, вопрос ясен, тема закрыта.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

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

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1099 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.