Страница 1 из 1

Socket, stream, bitmap, picture.Не получается

Добавлено: 30 авг 2006, 07:55
Dr_Grizzly
Всем привет! Такая вот задачка, есть два приложения, один сервер другой клиент, соединяются по Socket; ServerSocket, ClientSocket. Server формирует следующее:

Код: Выделить всё

var
 Bm: TMemoryStream;
  bmp: TBitmap;
  DC: HDC;
...
begin
    bm := TMemoryStream.Create;
    bmp:=TBitmap.Create;
    bmp.Height:=Screen.Height;
    bmp.Width:=Screen.Width;
    DC:=GetDC(0); 
    bitblt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height,
    DC, 0, 0, SRCCOPY);
    bmp.SaveToStream(bm);
    ReleaseDC(0, DC);
    end;
Теперь я это все дело отправляю клиенту:
ServerSocket1.Socket.SendStream(bm);

И вот загвоздка, не знаю как получить это у клиента. Что писать на OnRead у ClientSocket? Нужно чтоб сформировался такой же Stream, который я загружу Image1.Picture.bitmap.loadfromstream();

Нашел такой вот код:

Код: Выделить всё

var
  Stream : TWinSocketStream;
  Buffer : array[0 .. 9] of Char;
...
  while Socket.Connected do
  begin
    try
      Stream := TWinSocketStream.Create(Socket, 60000);
      try
        FillChar(Buffer, 10, 0); { initialize the buffer }
        { give the client 60 seconds to start writing }
        if Stream.WaitForData(60000) then  

        begin
          if Stream.Read(Buffer, 10) = 0 then { if can’t read in 60 seconds }
            Socket.Close;               { close the connection }
          { now process the request }

        end
        else
          Socket.Close; { if client doesn’t start, close }
      finally
        Stream.Free;
      end;
     except
  end;
 end;

это на обработчике события ClientSocket1Read... не врублюсь что тут за код и как его использовать :)

Добавлено: 31 авг 2006, 03:22
Naeel Maqsudov
Это пример из хелпа.
Это обработчик события OnExecute потока (нити) TServerClientThread.
Т.е. он предназначен для многопоточной работы.

Суть такова: в отдельной нити все что в сокет приходит - складывается в Stream. Т.е. организуется FIFO стек, чтобы не потерять значение внутреннего буфера сокета.
Многопоточная работа с сокетом необходима, если ессть вероятность, что во время обработки очередной порци данных поступит более одного пакетика. Т.е. чтобы избежать потери данных.

Добавлено: 31 авг 2006, 10:51
Dr_Grizzly
Хорошо, тогда как мне реализовать такую передачу без создания файла? Т.е. передать картинку рабочего стола без образования файла, потоком...

Добавлено: 31 авг 2006, 12:10
Игорь Акопян
Dr_Grizzly, использовать RAdmin :P
всё, всё, ухожу :)

Добавлено: 02 сен 2006, 00:24
Naeel Maqsudov
Хорошо, тогда как мне реализовать такую передачу без создания файла?
Там и не создается никаких файлов. TMemoryStraem используется для буферизации.
Одно приложение (сервер) пишет данные в поток, и посылает данные из потока в сокет.
Другое (в отдельной нити) читает из сокета в поток. А в основной нити - ждет, когда накопилтся в потоке необходимое количесство данных, и забирает их из потока.

Т.е. в клиентском приложении Вам надо добавить нить TThread и в ее событии OnExecute читать данные из сокета в поток.
А вот уже в положить, например, таймер, и раз в таймаут проверять содержимое потока и обрабатявать.

Разуммется параллельно Вам придется озадачиться массой вопросов:
1) как отделить один кусок данных от другого. (Не думайте, что один факт отправки данных точно соответствует одному факту приема данных)?
2) что делать при переполнении потока (некий размер потока должен быть опредделен как предельный, иначе приложение потенциально будет способно забрать всю доступную ввиртуальную память)?
3) что делать при частичной потере данных? Если чать кадра потерялась, то надо будет пропустить этот кадр и найти начало следующего.

Т.е. говоря другими словани сокеты - это транспортный уровень взаимодействия а не прикладной. Вам еще предстоит разработать прикладной протокол поверх TCP/IP.

Добавлено: 05 сен 2006, 05:56
Dr_Grizzly
Кошмар! А вроде казалось бы, чего там такого :)