Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2003.01.20;
Скачать: [xml.tar.bz2];

Вниз

Как передать поток не зная его длинны   Найти похожие ветки 

 
lats   (2002-11-20 15:52) [0]

Передать поток, а на клиенте его обрабатывать в реальном времени. Ну например график рисовать в зависимости от значений в потоке.


 
Digitman   (2002-11-20 16:39) [1]

поток на то и поток, что не имеет пределов)

а вот как ты себе мыслишь построение какого-либо графика вообще, без предварительного знания пределов/масштаба аргументов и значений ф-ции - это непонятно

поясни


 
Troll   (2002-11-20 16:47) [2]

2lats:
просто определи конечный символ, если ты подаешь цифры то подается такая строчка:
12@3@45@67@45@
это значит что в первую секунду значение 12 во вторую 3 и так далее. все будет обрабатыватся в реал-тайм.


 
lats   (2002-11-20 16:50) [3]

Знаю как передать поток через сокет, но там нужно знать где конец. Нужно передать звук. Я такой вопрос уже задавал. Только в другой интепретации. Звук с микрофона запихнуть в поток могу. А как принять не знаю.


 
lats   (2002-11-20 16:55) [4]

Посекундно может и будет работать, а для скорости звука? :)?
Cомневаюсь


 
Anatoly Podgoretsky   (2002-11-20 16:55) [5]

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


 
lats   (2002-11-20 17:00) [6]

C двумя каналами это интересно. Большое спасибо. Может ещё какие предложения будут?


 
Digitman   (2002-11-20 17:03) [7]


> lats © (20.11.02 16:50)
> Знаю как передать поток через сокет, но там нужно знать
> где конец


Где это - "там" ? Какой такой "конец" ? Что есть в этом случау "поток" ?


 
lats   (2002-11-21 08:05) [8]

Там это на клиенте. Но это уже не актуально.
Есть другой вопрос. Хотя он скорее для другого форума.
Как полученный поток передать на звуковую карту? Да чуть не забыл. Передавать нужно в реальном времени.


 
Digitman   (2002-11-21 08:11) [9]

полученный "поток" дели на блоки одного и того же нужного размера и передавай адреса блоков в WaveOut device


 
lats   (2002-11-21 08:25) [10]

А монжно подробнее? Как разделить на блоки?


 
Digitman   (2002-11-21 08:41) [11]

а что ты подразумеваешь под понятием "поток" ? именно - получаемый клиентом ? как это в наст.момент у тебя реализовано ? покажи код - будут и комментарии/рекомендации


 
lats   (2002-11-21 09:27) [12]

Конкретно со звуком ещё не делал.
Сейчас есть работающая программа, которая передает окно другой программы (рисунок)клиенту, который этот рисунок отображает.

коды примерно такие:

сервер:

var
ms: TMemoryStream;
WinDC: HDC;
WD : HWnd;
ARect : TRect;
Result : TBitMap;
t:TFileStream;
i : Integer;

begin
WD := MyWinWnd;
Result := TBitmap.Create; // Создаем рисунок, куда будем копировать
GetWindowRect(WD, ARect); // Узнаем размер
with Result, ARect do
begin
Width := ARect.Right - ARect.Left;
Height := ARect.Bottom - ARect.Top;
If (Width=0) or (Height=0) then
Begin
MessageDlg("Размер области формы равен нулю",
mtWarning,[mbOk],0); // А вдруг у него нет размера ???
Exit; // Тогда выходим
End;
WinDC:=GetWindowDC(Wd); // получаем для окна контекст устройства
ShowWindow(Wd, SW_SHOW); // на всякий случай выведем окно
BringWindowToTop(WD); // и поместим поверх окон
try
// копируем оттуда прямоугольную область на канву
// растрового изображения
BitBlt( Canvas.Handle, 0, 0, Width, Height, WinDC, 0, 0, SRCCOPY);
finally
end;
end;


if Socket.ReceiveText = "send" then
begin
ms:= TMemoryStream.Create;
try // Получаем данные на передачу.
Result.SaveToStream(ms);
ms.Position:= 0;
// Добавляем длину данных, чтобы клиент знал, сколько данных будет передано
// Добавляем #0 , чтобы можно было определить, где заканчивается информация о размере.
Socket.SendText(IntToStr(ms.Size) + #0);
// Посылаем его.
Socket.SendStream(ms);
except
// Итак, осталось освободить поток, если что-то не так.
ms.Free;
end;
end;
Result.Free;
end;


клиент:

var
s, sl: string;
begin s:= Socket.ReceiveText;
// Если мы не в режиме приёма:
if not Reciving then
begin
// Теперь нам необходимо получить длину потока данных.
SetLength(sl, StrLen(PChar(s))+1);
// +1 for the null terminator
StrLCopy(@sl[1], PChar(s), Length(sl)-1);
DataSize:= StrToInt(sl);
Data:= TMemoryStream.Create;
// Удаляем информацию о размере из данных.
Delete(s, 1, Length(sl));
Reciving:= true;
end;
// Сохраняем данные в файл, до тех пор, пока не получим все данные.
try
Data.Write(s[1], length(s));
if Data.Size = DataSize then
begin
Data.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(Data);
Data.Free;
Reciving:= false;
end;
except
Data.Free;
end;
end;


 
Digitman   (2002-11-21 10:05) [13]

1. Непонятно мне, что за блажь такая - передавать префикс размера данных в текстовом формате. Зачем нужно это бестолковое преобразование : на сервере IntToStr(размер), на клиенте StrToInt(размер) ? Что, разве нет способа передачи значения 4х-байтной переменной, содержащей размер следом идущего потока, в бинарном виде ?

2. Почему ты так уверен, что на сервере условие
if Socket.ReceiveText = "send" then
всегда выполнится ? А если ReceiveText вернет строку "sen" ? А при следующем OnClientRead() - "d" ? Или "sendsend" (если клиент двы раза команду послал, а принята она сервером как единая) ? В условиях, отличающихся от односегментной ЛВС (не говоря уже о тестировании клиента и сервера на одной и той же машине) такое вполне вероятно

3. Равно как и на кл.стороне :
s:= Socket.ReceiveText;

на основании чего такая уверенность, что s обязательно будет содержать строку длиной не меньшей, чем строка, посланная сервером при Socket.SendText(IntToStr(ms.Size) + #0) ? А если, например, на сервере ms.Size = 123456789, а клиент в первом же событии OnRead() получит лишь часть строки - "123456", а очередная "порция" "789#0XXXXXXXXX..." поступит лишь в следующем событии OnRead() ? Что будешь делать ? Принимать поток заведомо неверного размера = 123456 байт ?

4. На осн.чего ты уверен, что эта строчка
Socket.SendStream(ms);
всегда успешно выполнится ?

Подумай. Неправильно это. Рано или поздно сбой твоей логики приема/передачи поточных данных в неблок.режиме неизбежен при таком алгоритме. Примитивен он и не учитывает многих особенностей неблок.гнезд в режиме TCP

Потом уже будем разговаривать о всяких там "блоках" и "звуковых картах".




 
lats   (2002-11-21 10:22) [14]

Здорово! А где можно обо всём этом почитать? Эти фрагментики были взяты из других программ (примеров.) Понятно примеров плохих. За неимением информации приходится так писать. Хотя эти коды работают уже около месяца и сбоев пока небыло. Так где правильные примеры? Я на всех сайтах находил только подобные.


 
Digitman   (2002-11-21 10:37) [15]

Да нахрена тебе такие "примеры" ? Тем более - заведомо примитивные и кривые ? Ты пойми - ну не существует шаблона исх.кода на все "случаи жизни" ! Всякая индивидуальная задача требует индивид.подхода к решению. И бездумное "сдирание" чьего-то кода в надежде авось как-нить приспособить его "под себя" ни к чему хорошему не приведет.

Пррежде чем разбирать такие "примеры", нужно хоть немного углубиться в теорию, выяснить особенности конкретного транспортного протокола и механизм взаимодействия прикл.задачи с транспортними объектами, каковые представлены в дан.случае в двух взвимосвязанных ипостасях - WinsockAPI и Делфи-компоненты, инкапсулирующие ф-ции из этого API.

Сходи сюда http://book.itep.ru и изучи от корки до корки. Хотя бы в части, касающейся протоколов TCP/UDP и основных ф-ций WinsockAPI, предоставляющих транспортно-диспетчерский интерфейс для работы с этими протоколами. Особенности же работы компонентов TServerSocke/TClientSocket очень тесно связаны с особенностями применения и работы этих "низкоуровневых" ф-ций : socket(), WSAAsyncSelect, connect(), bind(), accept(), send()/recv() и т.д. и т.п.


 
Digitman   (2002-11-21 10:52) [16]

Общеправильным для протокола TCP при работе принимающей стороны будет запрос на чтение из гнезда (за один прием, т.е. в одном событии, если режим - неблокирующий) ровно такой порции данных, сколько ожидается в дан.момент по логике, но не более размера буфера приема гнезда (см. GetSockOpt(..so_rcvbuf))

иными словами, если по логике ожидается, что в дан.момент передатчик должен отправить 4 байта размера, то и принимать следует не более 4-х байт. Принял меньше ? Не беда, возникнет очер.событие OnRead() и оставшиеся еще непрочитанными байты размера повторно запрашиваются для чтения. И так, пока все 4 байта не будут прочитанными. Тут же твоя машина состояния переводится в статус RECEIVING и в каждом из очередных событий OnRead() делаются попытки чтения из гнезда блока размером не более чем rcvbuf_size, до тех пор пока суммарный размер действительно принятых (за N событий OnRead) данных не будет = DataSize


 
lats   (2002-11-21 10:58) [17]

Огромное спасибо Сергей! Ученье - свет. Пойду грызть гранит науки. Хорошо, что на свете есть умные люди (это про Сергея).



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

Форум: "Сети";
Текущий архив: 2003.01.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.013 c
6-62688
lats
2002-11-20 15:52
2003.01.20
Как передать поток не зная его длинны


14-62746
stainer
2003-01-04 13:19
2003.01.20
popupmenu отображается медленно


1-62474
KoHe4Ho }|{e 6ot
2003-01-09 22:59
2003.01.20
Плиззззз !!!


14-62844
Asteroid
2003-01-02 14:00
2003.01.20
Windows без глюков нельзя назвать полноценным, но все же...


3-62352
DiLLeR
2002-12-23 13:59
2003.01.20
В чем разница между IBSQL и IBQuery?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский