Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с компонентами TidTCPServer и TidTCPClient [D7, WinXP]


Страницы:   1 2 3

maxistent ©   (2009-11-30 06:57:00) 

Доброго времени суток. Подскажите как правильно использовать компоненты TidTCPServer и TidTCPClient для передачи данных? На сервере в OnExecute можно просто сделать что-то вроде AThread.Connection.ReadBuffer(Data,DataSize)? или надо как-то по-особому обрабатывать этот эвент? Собственно проблема вот в чем: пишу софт для передачи картинки с экрана в реалтайме (ну или почти в реалтайме). Получилось что-то вроде этого:

с клиента передаю данные idTcpClient1.WriteBuffer(...);

на сервере принимаю так:


procedure TForm1.ss1Execute(AThread: TIdPeerThread);
var
buf1,buf2:pointer;
DataSize:integer;
st:TStream;
jpg:TJPEGImage;
r:TRect;
begin
AThread.Connection.ReadBuffer(DataSize,sizeof(DataSize));
AThread.Connection.ReadBuffer(r,sizeof(r));
GetMem(buf1,DataSize);
AThread.Connection.ReadBuffer(buf1^,DataSize);
st:=TMemoryStream.Create;
st.Write(buf1^,DataSize);
FreeMem(buf1,DataSize);
st.Position:=0;
jpg:=TJPEGImage.Create;
jpg.LoadFromStream(st);
st.Free;
image1.Picture.Bitmap.Canvas.draw(r.Left,r.Top,jpg);
jpg.Free;
end;


При подключении начинается передача изображения, но через несколько секунд (~5 сек) изображение перестает обновляться, а еще через несколько секунд прога "вылетает" с сообщением <Canvas does not allow drawing>. что здесь не так? не могу понять...


maxistent   (2009-12-01 09:31:00) [21]

в [14] да, а вот в [20] не совсем. поэтому и прошу объяснить


Сергей М.   (2009-12-01 09:28:00) [22]

> что делать даже не знаю

Ему про фому, он всё про ерему)

Ты в [14],[20] вник ?


maxistent   (2009-12-01 09:27:00) [23]


> Сергей М. ©   (01.12.09 08:23) [20]

Не пойму как это применить? можно пояснить что к чему? например что есть ptrDataReadFromClient? указатель на TJPEGImage? и что за сообщение такое WM_DATA_TO_RENDER_AVAIL? что в этом блоке кода происходит, объясни если не сложно?


maxistent   (2009-12-01 09:15:00) [24]

в общем, пробывал сделать по таймеру, пипец получается. в смысле, задержка большая. пробывал в отдельном потоке - тут одно из двух, либо ошибка (типа не успевает прорисовываться, JPEG Error #43,#52 и т.д.), либо, если поставить что-то вроде sleep(1/5/10) то опять-таки тормозит :( что делать даже не знаю..


Сергей М.   (2009-12-01 08:23:00) [25]


> maxistent ©   (30.11.09 17:38) [15]


Например, так:

var
 ptrDataToRender: Pointer;
..
 ptrDataToRender := SysGetMem(dwBytesReadFromClient);
 try
   CopyMemory(ptrDataReadFromClient, ptrDataToRender, dwBytesReadFromClient);
   PostMessage(MyRenderForm.Handle, WM_DATA_TO_RENDER_AVAIL, Pointer(dwBytesReadFromClient), Self);
 except
    FreeMem(ptrDataToRender);
    raise;
 end;


brother   (2009-12-01 05:00:00) [26]

> 20 мс большая задержка?

а откуда такая точность?


CrytoGen   (2009-11-30 20:20:00) [27]

20 мс большая задержка?


maxistent   (2009-11-30 19:43:00) [28]

блииин... тогда задержки большие будут :( а другие, более "гуманные" варианты (в плане быстродействия) существуют?


CrytoGen   (2009-11-30 17:58:00) [29]

например использовать Synchronize - что не очень удобно
или сделать примерно так

var
 GlobalImage    : TBitmap;
 newImageFlag : boolean;
...
//получение данных
GlobalImage.Assign(TCPImage);
newImageFlag:=True;
...
//таймер
if newImageFlag then
begin
 Image1.Canvas.Draw(0,0,GlobalImage);
 newImageFlag:=False;
end;
...


maxistent   (2009-11-30 17:38:00) [30]

ну например как? допустим у меня на форме динамически создаются объекты TImage. в них нужно выводить в определенных местах небольшие графические фрагменты (что-то вроде Image1.picture.bitmap.canvas.draw(x,y,jpg))
но делать это надо после того, как будет получен от клиента очередной фрагмент, в событии OnExecute


Сергей М.   (2009-11-30 15:10:00) [31]

Известно как - извещать (любым удобным способом, синхронно или асинхронно - выбор за тобой) осн.поток о необходимости отрисовки там-то таких-то граф.данных.


maxistent   (2009-11-30 15:04:00) [32]

и как быть?


Сергей М.   (2009-11-30 14:32:00) [33]

Рисование на канве VCL-контролов в доп.потоках недопустимо.


maxistent   (2009-11-30 13:53:00) [34]

вроде разобрался, но появилась такая проблема:
я в потоке TIdPeerThread получаю изображение, потом пытаюсь его вывести на экран и "вылетает ошибка". я так понимаю мне нужно из этого потока как-то "временно выйти" (илипоставить на паузу), произвести отрисовку, и пото вернуться обратно? или я что-то не так понимаю? :(


Сергей М.   (2009-11-30 10:04:00) [35]


> Почему же ерунду?


Потому что.

Читать сюда

http://www.delphimaster.ru/cgi-bin/forum.pl?n=18&id=1251710046

до полного просветления.

В особенности пост [61] - это как раз твой печальный случай.

И не надо ходить по лесу из граблей.


maxistent   (2009-11-30 09:47:00) [36]


> CrytoGen   (30.11.09 08:41) [4]

сделал по твоему примеру, вроде работает. спасибо.


maxistent   (2009-11-30 09:37:00) [37]

ну на стороне клиентов проще - там просто в потоке я читаю вот так:
idTCPClient.ReadBuffer(buf,x)и мне этого в принципе достаточно, а с отправкой вообще никаких проблем. А вот как на стороне сервера отправить всем или выборочным клиентам данные - не знаю. допустим, на сервере выполнили действие ОТПРАВИТЬ СООБЩЕНИЕ (образно), выбрали ВСЕХ или НЕСКОЛЬКИХ клиентов и он должен этим клиентам разослать это сообщение. вот как это сделать я не знаю. подскажите?


maxistent   (2009-11-30 09:32:00) [38]


> CrytoGen [4]


А что за TCPTranslation? это к чему относится?


> brother ©   (30.11.09 08:43) [5]
> > На сервере нужно всем клиентам рассылать команды
> кстати, какие? тыж вроде хочешь слать картинки?


я посылаю комманду, а за ней уже идут данные (например, изображение)


> Сергей М. ©   (30.11.09 09:06) [6]
> Ерунду ты задумал. Либо клиент командует серверу и тот исполняет команды, либо наоборот.


Почему же ерунду? клиенты выполняют команды сервера, а сервер в свою очередь выполняет команды клиентов. поэтому мне и нужно реализовать двухсторонний обмен данными.


Сергей М.   (2009-11-30 09:06:00) [39]


> maxistent ©   (30.11.09 08:14) [2]



> двухстороннюю связь


Ерунду ты задумал.
Либо клиент командует серверу и тот исполняет команды, либо наоборот.


brother   (2009-11-30 08:43:00) [40]

> На сервере нужно всем клиентам рассылать команды

кстати, какие? тыж вроде хочешь слать картинки?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо