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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получение потока через сокет 
:(
    Опции темы
TP@MB@Y
Дата 26.6.2005, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

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



Я пишу прогу на подобие радмина. Сервер делает картинку и отсылает ее клиенту. Клиент получает картинку и выводит на экран.

Только что-то я совсем запутался и ничего не работает =)

Перед передачей потока я bmp в jpg преобразую

Серверная часть:
Код

procedure TfMainS.tTimerTimer(Sender: TObject);
var bmp:TBitmap;
    DC:HDC;
    buf:TJPEGImage;
    i:integer;
    stream:TStream;
begin
 DC:=GetDC(0);
 bmp:=TBitmap.Create;
 bmp.Height:=Screen.Height;
 bmp.Width:=Screen.Width;
 BitBlt(bmp.Canvas.Handle,0,0,Screen.Width,Screen.Height,DC,0,0,SRCCOPY);
 buf:=TJPEGImage.Create;
 buf.Assign(bmp);
 stream:=TStream.Create;
 buf.SaveToStream(stream);
 for i:=0 to ssServer.Socket.ActiveConnections-1 do
  ssServer.Socket.Connections[0].SendStream(stream);
 buf.Free;
 bmp.Free;
 stream.Free;
end;


Клиентская часть:
Код

procedure TfMainC.csClientRead(Sender: TObject; Socket: TCustomWinSocket);
var Stream:TStream;
begin
 Stream:=TStream.Create;

 //... ????

 Stream.Free;
end;


Как надо передавать потоки?
PM   Вверх
RA
Дата 26.6.2005, 05:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

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



Идём сюда за примером http://forum.vingrad.ru/index.php?showtopi...ndpost&p=328425
PM   Вверх
TP@MB@Y
Дата 26.6.2005, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

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



RAdmin
Смотрел код, но там много лишнего. Сути не уловил. Тебе наверно будет намного легче скопировать сюда нужные куски кода. Если не затруднит конечно же smile
PM   Вверх
RA
Дата 26.6.2005, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

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



Еще как затруднит, поэтому-то я и выложил этот пример. smile

Кстати в моём примере клиент осущесвляет отправку через SendText, а тебе наверное нужно через sendBuf, но разницы между двумя способами почти нету.


Сервер отправляет:

Код

..........
ServerSocket1.Socket.Connections[0].SendStream(MyFileStream);
............



Клиент принимает:

Код

procedure TForm1.ClientSocket1Read(Sender: TObject;
    Socket: TCustomWinSocket);
   var l: Integer;
       buf: PChar;
       fs: TFileStream;
  begin
  

   i := Socket.ReceiveLength;

    GetMem(buf,i+1);
   
    Socket.ReceiveBuf(buf,l);
    fs:= TFileStream.Create('c:\bmp',fmOpenReadWrite);
    fs.Seek(0,soFromEnd);
    fs.WriteBuffer(buf,l);
    fs.Free;
    FreeMem(buf);










PM   Вверх
TP@MB@Y
Дата 27.6.2005, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

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



RAdmin
Не пашет smile

Во-первых: у меня изображение в памяти находится (jpg) и пытаюсь его послать не сохраняя в отдельном файле. Но как это сделать правильно? Через sendstream или sendbuf (оба варианта пробовал, но всеравно не работает).
Вот что на данный момент при отсылке:
Код

var bmp:TBitmap;
    DC:HDC;
    jpg:TJPEGImage;
    buf:TStream;
begin
.................
 //Ïðåîáðàçóåì bmp â jpg
 jpg:=TJPEGImage.Create;
 jpg.Assign(bmp);
 //Îòñûëàåì êàðòèíêó
 buf:=TStream.Create;
 jpg.SaveToStream(buf);
 ssServer.Socket.Connections[0].SendBuf(buf,buf.Size);
 buf.Free;
 bmp.Free;
 jpg.Free;


Кстати, почемуто ругается на освобождение памяти...

Во-вторых: при получении вот что пишу:
Код

var jpg:TJPEGImage;
    buf:^byte;
    l:integer;
begin
 l:=Socket.ReceiveLength;
 GetMem(buf,l);
 Socket.ReceiveBuf(buf^,l);
 jpg:=TJPEGImage.Create;
 jpg.LoadFromStream(TStream(buf));
 iOutput.Picture.Assign(jpg);
 FreeMem(buf);
 jpg.Free;


Поидее должно работать но не работает =(

Ну почему все так сложно???
PM   Вверх
RA
Дата 27.6.2005, 04:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

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



Пардон, я без делфей, думал ты сам разберешься.

Тогда:
Код


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ScktComp, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    ClientSocket1: TClientSocket;
    ServerSocket1: TServerSocket;
    Button1: TButton;
    procedure Image1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
    Reciving: boolean;
    DataSize: integer;
    Data: TMemoryStream;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Image1Click(Sender: TObject);
begin
  // Это пpоцедуpа для откpытия сокета на ПРИЁМ (RECEIVING).
  // Button1.Click is this procedure as well.
  ClientSocket1.Active:= true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Откpытие ОТПРАВЛЯЮЩЕГО (SENDING) сокета.
  ServerSocket1.Active:= true;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  // Посылаем команду для начала пеpедачи файла.
  Socket.SendText('send');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  s, sl: string;
begin
  s:= Socket.ReceiveText;
  // Если мы не в pежиме пpиёма:
  if not Reciving then
  begin
    // Тепеpь нам необходимо получить длину потока данных.
    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;
    // Удаляем инфоpмацию о pазмеpе из данных.
    Delete(s, 1, Length(sl));
    Reciving:= true;
  end;
  // Сохpаняем данные в файл, до тех поp, пока не получим все данные.
  try
    Data.Write(s[1], length(s));
    if Data.Size = DataSize then
    begin
      Data.Position:= 0;
      Image2.Picture.Bitmap.LoadFromStream(Data);
      Data.Free;
      Reciving:= false;
      Socket.Close;
    end;
  except
    Data.Free;
  end;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  ms: TMemoryStream;
begin
  // Клиент получает команду на пеpедачу файла.
  if Socket.ReceiveText = 'send' then
  begin
    ms:= TMemoryStream.Create;
    try
      // Получаем данные на пеpедачу.
      Image1.Picture.Bitmap.SaveToStream(ms);
      ms.Position:= 0;
      // Добавляем длину данных, чтобы клиент знал, сколько данных будет
пеpедано
      // Добавляем #0 , чтобы можно было опpеделить, где заканчивается
инфоpмация
о pазмеpе.
      Socket.SendText(IntToStr(ms.Size) + #0);
      // Посылаем его.
      Socket.SendStream(ms);
    except
      // Итак, осталось освободить поток, если что-то не так.
      ms.Free;
    end;
  end;
end;

end.




взято с:
http://timhome.hut.ru/delphi/myFAQ_Delphi01.htm



PM   Вверх
TP@MB@Y
Дата 29.6.2005, 01:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

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



RAdmin
Вроде все работает, но только не совсем =)

Посылается вроде нрмально, но смотрю в отладчике и вижу:
после операции
Код

Data.Write(s[1], length(s));

в Data.Size лежит ноль. Хотя строка s не пустая. В чем может быть проблема?
PM   Вверх
RA
Дата 29.6.2005, 06:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

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



Мистика, свойство Size в потоках всегда возвращает число байт.


Код

procedure TForm1.Button1Click(Sender: TObject);
var Data: TMemoryStream;    s:string;
begin
 s:='sss';
 Data:= TMemoryStream.Create;
 Data.Write(s[1], length(s));
 Memo1.lines.add(IntTostr(Data.Size));
 Data.Free;
end;

PM   Вверх
TP@MB@Y
Дата 29.6.2005, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

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



RAdmin
Заработало!!!!! Глюк был из-за того, что переменная потока была локальной у меня.

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

Запрещено:

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

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

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

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

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


 




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


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

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