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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема в Сокетах. Пересылка больших объемов ин 
:(
    Опции темы
BigMazy
Дата 10.11.2004, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Доброго времени суток!
Возникла проблема которую мне необходимо решить
Имеется программа сервер. Я пишу свою программу клиента
Сервер на запросы клиента может отправлять ответы большого размера.

Естественно эти ответы отправляются по сокетному потоку порциями, которые необходимо склеить
Проблема состоит в следующем - эти порции приходят с задержками и клиент не успевает
получить все порции и считывает 0 байт, завершая прием.
Получается, что мне необходимо ставить WaitForData (ждать определенное время) на каждый проход
цикла по склеиванию полученных порций. Но тогда, обязательно и всегда будет весомая задержка в самом конце
работы цикла, когда все данные получены и серверу нечего уже отправлять.Получается, что при получении
данных всегда будет срабатывать задержка.

Как избавится от задержки в конце работы цикла?

Вот код процедуры получения данных, где ожидается только начало получения информации. Эта функция
в реальных услових работает не корректно, так как сервер не успевает отправить все порции данных.
Что делать ? Реально нужна Ваша помощь.
Может предложите свой вариант решения

Код
function ReadLongInfo(SocketStream: TWinSocketStream; ClientSocket: TClientSocket;var pData: pChar):byte;
var
pBuffer: pChar;
size_Receive: cardinal;
size_count: cardinal;
size: cardinal;
F: textFile;
A: TASyncStyles;
begin
result:=0;
pBuffer:=nil;
//Вот ждем когда начнется передача
if SocketStream.WaitForData(30000)=false
then
begin
 result:=1;
 exit;
end;
size_count:=0;
// Цикл склеиваения
repeat
 size_Receive:=ClientSocket.Socket.ReceiveLength;
 ReAllocMem(pBuffer,size_Receive);
 if size_Receive<>0
 then
 begin
 size:=SocketStream.Read(pBuffer^,size_Receive);
 size_count:=size_count+size;
 ReAllocMem(pBuffer,size);
 ReAllocMem(pData,size_count);
 MoveMemory(pData+size_count-size,pBuffer,size);
 fillMemory(pBuffer,size,0);
 end;
until size_receive=0;
// Конец цикла
freeMem(pBuffer);
end;

PM MAIL   Вверх
p0s0l
Дата 10.11.2004, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Можно упростить так:
Код
// Цикл склеиваения
repeat
 size_Receive:=ClientSocket.Socket.ReceiveLength;
 if size_Receive<>0
 then
 begin
 ReAllocMem(pData,size_count + size_Receive);
 size:=SocketStream.Read((pData+size_count-size_Receive)^ ,size_Receive);
 size_count:=size_count+size;
 end;
until size_receive=0;
Только если у тебя большие объёмы данных, то эти ReAllocMem'ы будут тормозить, т.к. это фактически может вылится в: выделение нового куска памяти, копирование инфы из старого куска, освобождение старой памяти...
Поэтому лучше либо:
1)перед посылкой данных сервер должен выслать размер передаваемых данных - выделяй сразу буфер такого размера
2)пиши получаемые данные в файл
3)вместо ReAllocMem делай GetMem, и запоминай адрес каждого буфера в массиве...



--------------------
С уважением, г-н Посол.
PM   Вверх
BigMazy
Дата 11.11.2004, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Благодарю !
PM MAIL   Вверх
BigMazy
Дата 11.11.2004, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Дело в том, что Сервер нанисан не мною, есть только exe-ник
Поэтому размер передаваемых данных включить в ответ сервера не получится.
Каким образом мне узнать, что сервер закончил передавать данные ?
Если использовать для этого размер полученного куска (если 0 - то конец),
то возникает ошибка, когда очередной кусок еще не отправлен, а мой
цикл уже определяет, что размер полученных данных =0, и следовательно, конец.
Пока я нашел решение просто в каждый проход цикла ставить waitForData

/|/ Цикл склеиваения
repeat
SocketStream.WaitForData(100);
size_Receive:=ClientSocket.Socket.ReceiveLength;
if size_Receive<>0
then
begin
ReAllocMem(pData,size_count + size_Receive);
size:=SocketStream.Read((pData+size_count-size_Receive)^ ,size_Receive);
size_count:=size_count+size;
end;
until size_receive=0;
Но такой способ будет давать обязательную задержку в конце приема даных, когда данные не подаются
и поток ждет определенное время.
Можно ли еще каким-то образом определить конец передачи данных.

PM MAIL   Вверх
p0s0l
Дата 11.11.2004, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Какие данные передаёт сервер (графуку, звук, текст или что еще ) ?
Формат известен ?
Всё равно либо должен идти вначале заголовок, из которого можно узнать длину, либо в конце завершающий сигнал должен быть...



--------------------
С уважением, г-н Посол.
PM   Вверх
BigMazy
Дата 13.11.2004, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Большое спасибо за помощь !
Там передаются такстовые скрипты, в виде набора макрокоманд.
В конце каждого скрипта идет команда END, по которой и можно определить
конец передачи.


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

Запрещено:

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

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

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

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

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


 




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


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

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