TClientSocket i Stream

0

Wiec tak jest funkcja sendStream, ale nie ma czegos w rodzaju RecvStream... czy cos mi umyka?

Chce wyslac bitmapke przez socketa, zapisuje TBitmap.SaveToStream(Stream);

Gdzie Stream to TMemoryStream, wysylam funckcja sendStream i nie wiem jak to odebrac :-8

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Stream: TStream;
  nReceived: Integer;
  Buffer: array [0..9999] of Char;
begin
  Stream := TMemoryStream.Create;
  try
    while True do begin
      nReceived := Socket.ReceiveBuf (Buffer, sizeof (Buffer));
      if nReceived <= 0 then
        Break
      else
        Stream.Write (Buffer, nReceived);
        Sleep (200);
      end;

    Stream.Position := 0;
    Worker.Picture.Bitmap.LoadFromStream(Stream);
  finally
    Stream.Free;
    Screen.Cursor := crDefault;
  end;
end;

Nie dziala, zna ktos moze cos prostrzego?

Moze wysylam to zle?

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TStream;
  q: Integer;
begin
  for q := 0 to ServerSocket1.Socket.ActiveConnections -1 do begin
    Stream := TMemoryStream.Create;
    Stream.Size := 5000;
    //Stream.Position := 0; - Oba sposoby sprawdzone
    Image1.Picture.Bitmap.SaveToStream(Stream);
    //Stream.Position := 0;
    ServerSocket1.Socket.Connections[q].SendBuf(Stream, Stream.Size);
    Stream.Free;
  end;
end;

Do tego po

Image1.Picture.Bitmap.SaveToStream(Stream);

obrazek znika, dlaczego?

Zna ktos moze jakis ciekawy artykul o tych sprawach?

0

Receivebuf() odbierze ci streama.

0

Chodzi ci o?

Stream := TMemoryStream.Create;
Stream.Size := Socket.RecieveSize;
Socket.ReceiveBuf (Stream, Socket.RecieveSize);

Nie dziala.

Albo czy zna ktos jakis inny sposob na wyslanie np TBitmap.

0

Chodzi ci o?

Stream := TMemoryStream.Create;
Stream.Size := Socket.RecieveSize;
Socket.ReceiveBuf (Stream, Socket.RecieveSize);

Nie dziala.

Albo czy zna ktos jakis inny sposob na wyslanie np TBitmap.

Wolverine - ...
moze na tyle z komentarzem a w praktyce?
(pisze z pamieci moga byc bledy)
wysylasz:

var
 M: TMemoryStream;
 B: TBitmap; // powiedzmy ze to juz istnieje
begin
 M := TMemoryStream.Create;
 M.Possition := 0; // !!!
 B.SaveToStream(M);
 M.Possition := 0; // !!!
 client.Socket.SendBuf(M, M.Size);

odbierasz:

..... onRead......
var
 M: TMemoryStream;
 B: TBitmap; // powiedzmy ze to nie istnieje :P
begin
 M := TMemoryStream.Create;
 B := TBitmap.Create;
 Socket.ReceiveBuf(M, Socket.ReceiveLength)
 M.Possition := 0; // !!!
 B.LoadFromStream(M);

W razie czego pisz... a tak BTW nie lepiej wysylac JPEGi??

0

Witam, o to mój całkiem działający, choć mało przydatny w warunkach normalnych, przykład:

var
  MStrm: TMemoryStream;
  MSize: Integer;
  Receiving: Boolean;

procedure TForm1.Button1Click(Sender: TObject);
var
  Size, I: Integer;
  Ms : TMemoryStream;
  Buf: Array[0..1023] of Byte;
begin
  Ms := TMemoryStream.Create;
  try
    Image1.Picture.Bitmap.SaveToStream(Ms);
    with ServerSocket1.Socket do
      for I := 0 to ActiveConnections -1 do
      begin
        Size := Ms.Size;
        Ms.Position := 0;
        Connections[I].SendBuf(Size, SizeOf(Size));
        while Ms.Position <> Ms.Size do
        begin
          Sleep(10); 
          Application.ProcessMessages;
          Size := Ms.Read(Buf, SizeOf(Buf));
          Connections[I].SendBuf(Buf, Size);
        end;
      end;
  finally
    Ms.Free;
  end;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Str : String;
begin
  Application.ProcessMessages;
  Str := Socket.ReceiveText;
  if not Receiving then
  begin
    MStrm := TMemoryStream.Create;
    Move(Str[1], MSize, 4);
    Delete(Str, 1, 4);
    Receiving := True;
  end;
  try
    MStrm.Write(Str[1], Length(Str));
    if MStrm.Size = MSize then
    begin
      MStrm.Position := 0;
      Image2.Picture.Bitmap.LoadFromStream(MStrm);
      MStrm.Free;
      Receiving := False;
    end;
  except
    MStrm.Free;
    Receiving := False;
  end;
end;
0

Wielkie dzieki! Mi tez sie to przyda! Wlasnie podsunales mi sposob do wysylania screenow robionych przez program na innym komputerze! Thanks! :-)


EEE, nie dziala... ;-|

Please, no more stupid questions...
(nie bierz tego do siebie)

Snowak [cygaro]

0

hmm no paranoja, po ciezkiej pracy ( ;p ) zklepalem se cos takiego:

type
  TStreamHeader = record
    Size: Integer;
  end;

var
  StreamSize: Integer;
  RcvStream : TMemoryStream;
  StreamTransfer: Boolean;

Wysylanie:
<font size="7">Ta czesc dziala idealnie</span>

var
  Bitmap: TBitmap;
  Ms : TMemoryStream;
  Buffer: array[0..8191] of Byte;
  Sent, Readed: Integer;
  StreamHeader: TStreamHeader;
begin
  Ms := TMemoryStream.Create;
  Ms.Position := 0;
  //Zapisuje se cos do strumienia
  
  //Wysylam naglowek
  StreamHeader.Size := Ms.Size;
  ServerSocket.Socket.Connections[0].SendBuf(StreamHeader, SizeOf(StreamHeader));

  //Wysylam pakiety
  Sent := 0;
  Ms.Position := 0;
  //dopuki nie zostanie wyslany caly stream
  while Sent < Ms.Size do begin
    Readed := Ms.Read(Buffer, SizeOf(Buffer));
    ServerSocket.Socket.Connections[0].SendBuf(Buffer, Readed);
    Sent := Sent + Readed;
    Readed := 0;
  end;
  Ms.Free;
  Bitmap.Free;
end;

Odbieranie:

function TMainForm.SaveBuffer(var Buffer: array of Byte; Size: Integer): Boolean;
begin
  //Sleep(100); - bez tego dziala w miare normalnie, choc jak cos sie zacznie robic na kompie, zaczyna sie sypac
  RcvStream.Write(Buffer, Size);
  StatusLabel.Caption := IntToStr(RcvStream.Size) + '/' + inttoStr(StreamSize);
  Result := True;
end;

procedure TMainForm.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  Downloaded: Integer;
  Buffer: array[0..8191] of Byte;
  StreamHeader: TStreamHeader;
begin
  //Jesli nie jest pobierany stream
  if not StreamTransfer then begin
    Socket.ReceiveBuf(StreamHeader, SizeOf(StreamHeader));
    RcvStream := TMemoryStream.Create;
    RcvStream.Position := 0;
    StreamSize := StreamHeader.Size;
    StreamTransfer := True;
    Exit;
  end;
  //Zapisywanie bufora
  Downloaded := Socket.ReceiveBuf(Buffer, SizeOf(Buffer)-1);
  if SaveBuffer(Buffer, Downloaded) then begin
    if RcvStream.Size >= StreamSize then begin
    //Tu se cos z tym robie...
    end;
  end;
end;

Problem pojawia sie jak np zlapie aplikacje za pasek, lub zrobie cos wymagajacego na kompie. Czyli wyglada na to, ze nie nadaza z zapisem do streama, a juz przychodzi nastepny pakiet, ma ktos jakis pomysl?

0

A, o to ci chodzi. No wiesz, mozna by przyblokowywac i zapisywac nastepne do plikow w danym katalogu.

Please, no more stupid questions... (- to nie jest glupie)
(nie bierz tego tak do siebie)

Snowak [cygaro]

0

Może już po czasie, ale fajny jest IdTCPClient
procedure TIdTCPConnection.ReadStream(AStream: TStream; AByteCount: Integer = -1; const AReadUntilDisconnect: Boolean = False);

0

Chciałbym zrobić program do monitorowania sieci - chciałbym widzieć obraz z ekranu. Jak przy pomocy Streamów coś takiego zrobić? Próbowałem samodzielnie, ale wywala błąd JPeg error #41?. Nie mam pojęcia jak to zrobić.
Robię tak:

Jpeg.loadFromStream(imgstream);
jpeg.savetofile('C:\tmp.jpg');
image1.picture.loadfromfile('C:\tmp.jpg');

No i wywala błąd
Co zrobić?
Z góry dzięki!

0

Problem pojawia sie jak np zlapie aplikacje za pasek, lub zrobie cos wymagajacego na kompie. Czyli wyglada na to, ze nie nadaza z zapisem do streama, a juz przychodzi nastepny pakiet, ma ktos jakis

Zrób przesyłanie potwierdzenia odebrania pakietu. Socket wysyłający będzie czekał na taki pakiet, a gdy go otrzyma to znaczy, że klient jest już gotowy do odbioru następnej paczki, więc zostanie mu ona wysłana.

Co do odczytu całości bufora do strumienia to można też tak:

var
  Stream: TMemoryStream;
begin
   Stream := TMemoryStream.Create;
   try
     Stream.SetSize(Socket.ReceiveLength);
     Socket.ReceiveBuf(Stream.Memory^, Stream.Size);
     // cos tam...
   finally
     Stream.Free;
   end;
end;
0

Tez mi sie to wydaje za najlepsze wyjscie...

0

Też za bardzo nie wiem jak strumieniami wysyłać pliki jpg i jak się zabezpieczyć m.in. przed błędem JPEG #41.

0

Powyzej masz odsyc ciekawy zasob funkcji do tego wiec wystarczy troche czasu i checi ...

0

Vegat - próbujesz ładować plik, zanim zostanie utworzony. Musisz wstawić sleep i to nie mały - na moim kompie potrzeba na to około 200-300 ms...

0
MrSquell napisał(a)
 M.Possition := 0; // !!!
 B.SaveToStream(M);
 M.Possition := 0; // !!!

Dzięki Ci człowieku za tą informację, że trzeba wracać do początku strumienia :) kompletnie o tym zapomniałem, przez co się namęczyłem ze strumieniami. Piwo dla Ciebie [browar]

1 użytkowników online, w tym zalogowanych: 0, gości: 1