переменную Jpeg из памяти в Socket

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by t04, 10 May 2009.

  1. t04

    t04 Elder - Старейшина

    Joined:
    10 Jan 2007
    Messages:
    137
    Likes Received:
    40
    Reputations:
    8
    Нужна помощь в отправке переменной типа TJpegImage в сокет "на лету" из памяти. вариант сохранить в файл а затем отправлять не предлагать

    перевожу сначала Jpeg в MemoryStream а затем стрим копирую в буфер, но уже при самом переводе из jpeg в memorystream облом какойто, размер картинки в два раза растет, а при передаче в буфер совсем ноль, может существует способ непосредственно используя переменную jpeg отправлять в сокет? :(

    PHP:
    procedure SendJpeg(JpegName:String);
    const
      
    PACKET_DATA_SIZE 16777216;//16*1024*1024//16ÌÁ
    type
      PByteArray 
    = ^TByteArray;
      
    TByteArray = array[0..PACKET_DATA_SIZE-1of byte;
    var
      
    Buf       PByteArray;
      
    jpg       TJpegImage;
      
    MemStream TMemoryStream;
      
    flw       File;
    begin
      jpg 
    := TJpegImage.Create;
      
    MemStream := TMemoryStream.Create;
      try
        
    jpg.LoadFromFile(JpegName);
        try
          
    jpg.SaveToStream(MemStream);
          
    GetMem(Buf,MemStream.Size);
          
    MemStream.WriteBuffer(Buf^,MemStream.Size);
          
    SendBuf(Sock,Buf^,MemStream.Size);

          
    jpg.SaveToFile('1.jpg');//сохраняется файл размером 3 кб
          
    MemStream.SaveToFile('C:\2.jpg');//сохраняется файл размером 6 кб

          
    AssignFile(flw,'C:\3.jpg');
          
    ReWrite(flw,1);
          
    BlockWrite(flw,buf^,MemStream.Size);//ничего не сохраняется
          
    CloseFile(flw);

          
    FreeMem(Buf);
        finally
        
    end;
      finally
        
    jpg.free;
        
    MemStream.Free;
      
    end;
    end
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    MemStream.WriteBuffer(Buf^,MemStream.Size); - это ты запишешь буфер в поток, а тебе нужно читать его типа ReadBuffer. Воть только не забывай устанавливать позицию на начала потока MemStream.position:=0; типа так
     
  3. t04

    t04 Elder - Старейшина

    Joined:
    10 Jan 2007
    Messages:
    137
    Likes Received:
    40
    Reputations:
    8
    Все равно ничего не вышло :(

    Видимо всте таки придется записать в файл а затем отправить в сокет :(
     
  4. Flame of Soul

    Flame of Soul Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    185
    Likes Received:
    146
    Reputations:
    45
    Способ 1.

    Можно воспользоваться компонентами TNMStrmServ и TNMStrm. Они специально предназначены для обмена потоками данных.


    PHP:
    //Обработчик для клиента: 
    var
      
    MyStreamTMemoryStream;
      
    JpgTJpegImage;
    begin
      
    ...
      
    //тут сами определите как у вас появляется Jpg
      
    ... 
      
    MyStream := TMemoryStream.Create;
      
    Jpg.SaveToStream(MyStream);
      
    NMStrm1.PostIt(MyStream);
      
    MyStream.Free;
    end;

    //Обработчик для сервера: 
    procedure TForm1.NMStrmServ1MSG(SenderTComponent;
    const 
    sFromstringstrmTStream);
    var
      
    MyStreamTMemoryStream;
    begin
      MyStream 
    := TMemoryStream.Create;
      
    MyStream.CopyFrom(strmNMStrmServ1.BytesTotal);
      
    MyStream.SaveToFile('c:\windows\1.jpg');
    end;
    2 Способ.

    рекомендую.


    PHP:
    private
      { Private 
    declarations }
      
    Recivingboolean;
      
    DataSizeinteger;
      
    DataTMemoryStream;
    ...

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

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


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

    end.

    удачи в написании))) не забывайте передавать зашифрованные данные.
     
  5. t04

    t04 Elder - Старейшина

    Joined:
    10 Jan 2007
    Messages:
    137
    Likes Received:
    40
    Reputations:
    8
    пишу без сервер/клиент сокета, использую ВинСок, поэтому не подходит вариант.

    Буду искать аналог юнита джипег или потрошить три-четыре модуля придется.
     
  6. Ryu

    Ryu New Member

    Joined:
    13 Jun 2008
    Messages:
    19
    Likes Received:
    3
    Reputations:
    2
    http://hellknights.void.ru/articles/0x48k-VisualSpy.htm

    Медитируй и просветлишся.

    З.Ы.Да, там правда автор синячит, но настоящему дельфину это перелопатить не составит труда, там голое АПИ
     
    #6 Ryu, 19 May 2009
    Last edited: 19 May 2009