przesylanie JPG miedzy ClientSocket <> ServerSocket

0

mam drobny problem... otoz robie sobie screen'a klikajac clienta na moim komputerze do servera na laptopie... wszystko ladnie sie robi, jpg zapisuje sie na dysku i tutaj nie wiem co zrobic... w jaki sposob wyslac/odeslac jpg do mojego komputera (klient) ??

0

na pewno jest w FAQu albo artach gtowe rozwiązanie

0

przejrzalem wszystko... ARTYKULY, FAQ, GOTOWCE i nic nie znalazlem na temat wysylania jpg przez ClientSocket i ServerSocket... :(

0

Dodaj w Kliencie Buttona i w OnClick dodaj coś takiego:

Client.WriteLn('GETIMG');

Client.ReadBuffer(Bufor, iledanychodczytac); //albo ReadStream(twoj strumien do pliku);

FreeAndNil(twoj strumien do pliku); //tylko w przypadku korzystania ze strumieni

i to by bylo na tyle..

a w Serverze w OnExecute dodaj

var
Command : String;
begin

Command := Server.ReadLn();

if Command = 'GETIMG' then
begin
AThread.Connection.OpenWriteBuffer;
AThread.WriteStream(strumiendopliku);
AThread.CloseWriteBuffer;
end;

</delphi>

0

ojjj nie za bardzo rozumie... u mnie to wyglada inaczej...

Client.WriteLn('blabla');

rowna sie u mnie:

ClientSocket1.Socket.SendText('blabla');

i jeszcze inne rzeczy

wiadomosc:string

if (wiadomosc='blabla')
then
begin
...
end;

a dalszej/innej wersji nie rozumie... moze ktos to wytlumaczyc jak powinno wygladac ? aby przeslalo obraz ? moze jakies strony ? artykuly ? faq ? cokolwiek ? :)

0

Z jakich komponentów korzystasz? Jeżeli z podstawowych (TClientSocket i TServerSocket) z D6, to raczej marnie to widzę...

Z bibliotekami Indy mi to lepiej szło... gdyż umieszczałem jeszcze komponent IdTrivialFTP. Klient wysyła żądanie (np. 'Te, idiota. Polacz sie ze mna na porcie tftp i pobierz plik'), a serwer grzecznie się podłącza i plik pobiera.

Jeżeli znacie lepsze sposoby, z chęcią wysłucham :D

[edit]
Przykładowy kodzik z mojej aplikacji zdalnego sterowania komputerem (xd)

if cmd = 'takescreenshot' then
        begin
                c := TCanvas.Create;
                c.Handle := GetWindowDC(GetDesktopWindow);
                b := TBitmap.Create;
                b.Width := screen.Width;
                b.Height := screen.Height;
                b.Canvas.CopyRect(Rect(0,0,screen.Width,screen.Height),c,Rect(0,0,screen.Width,screen.Height));
                jpg := TJpegImage.Create;
                jpg.CompressionQuality := 80;
                jpg.Assign(b);
                jpg.Compress;
                jpg.SaveToFile('c:\clipboard.jpeg');
                SendCmdP('screenshotavailable',socket,'c:\clipboard.jpeg'); // Poinformuj klienta o tym, ze plik jest juz gotowy.
        end;

A tutaj kodzik klienta:

        if cmd = 'screenshotavailable' then
        begin
                IdFTP.Get(lparam,'tmp.jpg');
                imgScreen.Picture.LoadFromFile('tmp.jpg');
                imgScreen.Stretch := true;
        end;
0

ZApisz obraz, wysylaj kazdy pakiet np. jak jest w przyklad z na kopiowanie plikow poprzez blockwrite 1024 bajty = 1KB array[0..1024]

dokladnie to jest cos takiego:

procedure TForm1.Button2Click(Sender: TObject);
var
f : file;
i : integer;
i2 : integer;
SrcF : file;
s : string;
  RealSize : Integer;  // realna odczytana wartość z pliku 
  Buffer : array[0..Count] of char;  // bufor przesyłanych danych 
  TotalSize : Integer; 

begin
Totalsize := 0;
AssignFile(SrcF, plik);
AssignFile(F, plik+'imo');
rewrite(f,1);
reset(SrcF,1);
Seek(SrcF, TotalSize);
s := edit1.text;
application.ProcessMessages;
repeat
BlockRead(SrcF, Buffer, SizeOf(Buffer), RealSize);
if RealSize > 0 then
begin
blockwrite(f,Buffer, RealSize);
TotalSize := TotalSize + RealSize;
end;
until RealSize = 0;
blockwrite(f,s,sizeof(s));
closefile(SrcF);
closefile(F);
end;

serwer - wysylasz wiadomosc ze chces przeslac obraz
klient - to odbiera i przesiada sie na tryb przesylania z kazdym pakietemn najlepiej przeslac rekord

type x= record
komenda : //tutaj to moze byc string i go bym polecal w wartosci np. string[25] na wlasne komendy
bajty:array[0..zakres] of byte;
end;

0

Huh... dobry pomysł... Ja korzystalem z czegos takiego

type TPackage = record
        cmd : string[255];
        cmdparam : array[1..5] of string[255];
        data : array[0..1024] of byte; // w oryginale tego nie ma, stworzone na potrzeby tego posta
  end;

(** FAR, FAR AWAY **)

clientsocket1.Socket.SendBuf(package,sizeof(package));

(** REALLY FAR AWAY (Server) **)

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var Package = TPackage;
begin
        socket.ReceiveBuf(Package,socket.ReceiveLength);
end;

No i tu moja wiedza się wyczerpała, gdyż mniej więcej w tym momencie pisania troja*a, przesiadłem się na dwa protokoły (tcp i tftp).

0

dziekuje za odpowiedzi :) teraz na pewno cos wykombinuje z tym jpg :) mam jeszcze jedno male pytanie... jak mozna zwiekszyc ilosc znakow przesylanych przez :

ClientSocket1.Socket.SendText(edit2.Text);

teraz mam tylko jakies 30... :( a przydaloby sie duzo wiecej...

0

Serwer:

uses Sockets, JPEG;

//..

var Server:TTCPServer;

procedure TForm1.FormCreate(Sender: TObject);
begin
Server:=TTCPServer.Create(self);
Server.LocalPort:='1234';
Server.Active:=TRUE;
Server.OnAccept:=TcpServerAccept;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Server.Free;
end;

procedure TForm1.TcpServerAccept(Sender: TObject; ClientSocket: TCustomIpClient);
var Size:integer;
    Stream:TMemoryStream;
    Komenda:integer;
    Canvas:TCanvas;
    Bitmap:TBitmap;
    Jpeg:TJpegImage;
begin
if (ClientSocket.ReceiveBuf(Komenda, sizeof(Komenda))=sizeof(Komenda)) then
  begin
  Stream:=TMemoryStream.Create();
  Canvas:=TCanvas.Create();
  Canvas.Handle:=GetWindowDC(GetDesktopWindow());
  Bitmap:=TBitmap.Create;
  Bitmap.Width:=Screen.Width;
  Bitmap.Height:=Screen.Height;
  Bitmap.Canvas.CopyRect(Rect(0,0,Screen.Width,Screen.Height),Canvas,Rect(0,0,Screen.Width,Screen.Height));
  Canvas.Free;
  Jpeg:=TJpegImage.Create();
  Jpeg.CompressionQuality:=80;
  Jpeg.Assign(Bitmap);
  Bitmap.Free;
  Jpeg.Compress;
  Jpeg.SaveToStream(Stream);
  Jpeg.Free;
  Size:=Stream.Size;
  if (ClientSocket.SendBuf(Size, sizeof(Size))=sizeof(Size))
  and (Size>0) then
    ClientSocket.SendBuf(PByte(Stream.Memory)^, Size);
  Stream.Free;
  end;
end;

Klient:

procedure TForm1.Button1Click(Sender: TObject);
var Client:TTCPClient;
    Size:integer;
    Stream:TMemoryStream;
    Komenda:integer;
begin
Client:=TTCPClient.Create(self);
Client.RemoteHost:='localhost';
Client.RemotePort:='1234';
Client.Active:=TRUE;
Komenda:=0;
if (Client.SendBuf(Komenda, sizeof(Komenda))=sizeof(Komenda))
and (Client.ReceiveBuf(Size, sizeof(Size))=sizeof(Size))
and (Size>0) then
  begin
  Stream:=TMemoryStream.Create;
  Stream.SetSize(Size);
  if (Client.ReceiveBuf(PByte(Stream.Memory)^, Size)=Size) then
    Stream.SaveToFile('c:\plik.jpg');
  Stream.Free;
  end;
Client.Free;
end;

Polecam zabezpieczyć funkcje Send/Receive za pomocą pętli, bo może się okazać, że wykonując się przeczytają tylko fragment wysłanego pliku, więc, póki funkcje te nie zwrócą wartości ujemnej lub zera (chyba, że pobrały już całość rozmiaru pliku) trzeba je ponownie wywoływać - taka już zaleta przesyłania większych danych po TCP/IP.

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