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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> чтение из блокирующего сокета 
V
    Опции темы
x77
Дата 22.5.2006, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

  ...
        cs.Active := FALSE;
        try
          ...
          cs.Active := TRUE;
          cs.Socket.SendText (ChildNode.xml);                              
          ss := TWinSocketStream.Create(cs.Socket, 60000);
          try
            Xml := '';
            repeat
              FillChar (Buf, nCount, #0);
              ss.WaitForData(10000);
              Count := ss.Read(Buf, nCount);
              Xml := Xml + Buf;
            until Count <> nCount;
          finally
            ss.Free;
          end;
          ...
        except
          on E: Exception do begin
          ...
          end;
        end;
      end;
    finally
      cs.Free;
    end;
  end;


здесь cs: TClientSocket, а Buf: array [0..nCount-1].

всё это работает. но для 20 клиентов у некоторых не вычитывается до конца буфер, что в итоге даёт ошибку при дальнейшей обработке получаемого XML. я пробовал менять константу nCount от 16 до 10000 - не помогло, просто ошибки начинают вылетать на других клиентах. Вообще что странно, несколько повторных запусков без изменения кода приводят к разным результатам, т.е. на некоторых клиентах, где возвращаемые ответы от сервака достаточно большие, эти ответы "недочитываются" до конца....

как заставить сокет гарантированно прочитать все данные? слать от сервера некий флаг и читать до его получения? или можно это как-то сделать на стороне клиента? 


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Sunr1se
Дата 22.5.2006, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 1.5.2006

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



Дело в том, что у всех сокетов есть ограничение на размер буфера. Так как данные со всех сокетов сваливаются в один буфер, то он быстро наполняется. 
--------------------
IRC-канал Винграда 
PM MAIL ICQ   Вверх
x77
Дата 22.5.2006, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Sunr1se, это прога для сбора инфы. она получает входной Xml, в котором расписано с каких компов какую инфу ндо получить. на одном компе висит клиент, работающий по приведённому коду. Ещё на 20 компах (которых я назвал клиентами, что не совсем верно), висит TServerSocket, ThreadBlocking. 

Клиент в цикле открывает подключения к этим 20 компам и вычитывает инфу в блокирующем режиме. Для каждого нового подключения сокет пересоздаётся. 

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


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Демо
Дата 22.5.2006, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

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



Код

            repeat    
              FillChar (Buf, nCount, #0);    
              ss.WaitForData(10000);    
              Count := ss.Read(Buf, nCount);    
              Xml := Xml + Buf;    
            until Count <> nCount;


В этом цикле данные могут и не успеть дойти до сокета. В какой-то момент цикл прервется на середине передачи.
Чтобы того не происходило, перед передачей самих данных передавай размер этих данных. Напрмиер, вполне подойдет Integer(4 байта), или, если данных более 2Гб - Int64(8 байт).

Добавлено @ 11:23 
Вот здесь обсуждался вопрос и приведены примеры.
http://forum.sources.ru/index.php?showtopi...l=tclientsocket

Если не успеешь проситать до того, как это сообщение удалят, стучи в приват. 


--------------------
    
PM MAIL ICQ Skype   Вверх
x77
Дата 22.5.2006, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Демо, попробую выставлять размеры ответа, спасибо smile 


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
drkot
Дата 22.5.2006, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

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



Поддершиваю Демо.
Если на опрашиваемых компах активер режим DirectX передача данных по сети заметно ухудшается. 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
x77
Дата 22.5.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



да, с проверкой длины, передаваемой сервером, всё работает:

Код
            ss.WaitForData(10000);
            ss.Read(Size, 2);
            Count := 0;
            repeat
              FillChar (Buf, nCount, #0);
              ss.WaitForData(10000);
              Count := Count + ss.Read(Buf, nCount);
              Xml := Xml + Buf;
            until Count = Size;



Демо, +1 ;) 


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

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

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

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

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

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


 




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


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

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