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

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
Dr_Grizzly
Сообщения: 407
Зарегистрирован: 13 сен 2004, 12:05
Откуда: Курган
Контактная информация:

Всем привет! Такая вот задачка, есть два приложения, один сервер другой клиент, соединяются по 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... не врублюсь что тут за код и как его использовать :)
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Это пример из хелпа.
Это обработчик события OnExecute потока (нити) TServerClientThread.
Т.е. он предназначен для многопоточной работы.

Суть такова: в отдельной нити все что в сокет приходит - складывается в Stream. Т.е. организуется FIFO стек, чтобы не потерять значение внутреннего буфера сокета.
Многопоточная работа с сокетом необходима, если ессть вероятность, что во время обработки очередной порци данных поступит более одного пакетика. Т.е. чтобы избежать потери данных.
Dr_Grizzly
Сообщения: 407
Зарегистрирован: 13 сен 2004, 12:05
Откуда: Курган
Контактная информация:

Хорошо, тогда как мне реализовать такую передачу без создания файла? Т.е. передать картинку рабочего стола без образования файла, потоком...
Аватара пользователя
Игорь Акопян
Сообщения: 1440
Зарегистрирован: 13 окт 2004, 17:11
Откуда: СПБ
Контактная информация:

Dr_Grizzly, использовать RAdmin :P
всё, всё, ухожу :)
Изображение
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

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

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

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

Т.е. говоря другими словани сокеты - это транспортный уровень взаимодействия а не прикладной. Вам еще предстоит разработать прикладной протокол поверх TCP/IP.
Dr_Grizzly
Сообщения: 407
Зарегистрирован: 13 сен 2004, 12:05
Откуда: Курган
Контактная информация:

Кошмар! А вроде казалось бы, чего там такого :)
Ответить