Delphi + Lazarus + Socket

Odpowiedz Nowy wątek
2011-08-31 11:17
0

Witam!
Nie dawno zacząłem się uczyć gniazd. (Indy 10 komponenty TIdTcpClient i TIdTcpServer ). Moim zamierzeniem jest zrobienie aplikacji serwerowej, z tym że pod Linuxem, zatem w linuxie pisze w Lazarusie. Kody które działały pod windowsami (Delphi) nie chcą działać pod lazarusem. Może ktoś robił podobną rzecz i będzie w stanie mi pomóc lub użyczyć kodu. Mój kod prezentuje się następująco. Dodam tylko że, raz się, łączy raz nie a raz wywala błąd o treści "raised exception class 'External: SIGSEGV'" pos stronie servera.

Kod
Po stronie Clienta:

Function TSocketF.WyslijSocketem(PlikISciezka:string):integer;
var
fileStream: TFileStream;
ch:integer;
begin
ch:=0;
PolaczZServerem();
 
fileStream := TFileStream.Create(PlikISciezka, fmOpenRead or fmShareDenyWrite);
try
  try
  USocket.SocketF.Client.IOHandler.writeln('SFILE');
  USocket.SocketF.Client.IOHandler.writeln(ExtractFilename(PlikISciezka));
  USocket.SocketF.Client.IOHandler.LargeStream:=true;
  Filestream.Position:=0;
  USocket.SocketF.Client.IOHandler.Write(filestream,filestream.Size,true);
 
  finally
  FreeAndNil(FileStream);
  end;
 
 except
 on E:Exception do
 begin
 glowny.ostrzezenie('Błąd wysyłania pliku');
 ch:=1;
 end;
 end;
 
 WyslijSocketem:=ch;
 end;
 
Procedure PolaczZServerem();
begin
try
//if USocket.SocketF.Client.Connected=true then
   USocket.SocketF.Client.Disconnect;
   USocket.SocketF.Client.IOHandler.Free;
 
   USocket.SocketF.Client.Host:=glowny.DaneFirmy(1).SERWER_HOST;
   USocket.SocketF.Client.Port:=glowny.DaneFirmy(1).SERWER_PORT;
   //USocket.SocketF.IdSSLIOHandlerSocketOpenSSL1.PassThrough:=false;
 
   USocket.SocketF.Client.Connect;
except
glowny.ostrzezenie('Problem z nawiązaniem połączenia z serwerem PBaza');
end;
end;

PO STRONIE SERVERA

procedure TSocketF.ServerExecute(AContext: TIdContext);
var
Akcja,NazwaPliku,Katalog:string;
FileStream:TFileStream;
begin
  if not USocket.SocketF.Server.Active then
  begin
    USocket.SocketF.server.Active := true;
  end;
    Katalog:=ExtractFilePath(Application.ExeName)+'Pliki\';
 while AContext.Connection.Connected do
begin
try
  Akcja:=AContext.Connection.IOHandler.ReadLn;
      if Akcja='SFILE' then
      begin
      NazwaPliku:=AContext.Connection.IOHandler.ReadLn;
      FileStream := TFileStream.Create(Katalog+NazwaPliku, fmCreate);
      AContext.Connection.IOHandler.LargeStream:=true;
      AContext.Connection.IOHandler.ReadStream(FileStream, -1, False);
      end;
 
      if Akcja='GFILE' then
      begin
      NazwaPliku:=AContext.Connection.IOHandler.ReadLn;
      fileStream := TFileStream.Create(Katalog+NazwaPliku, fmOpenReadWrite);
      AContext.Connection.IOHandler.LargeStream:=true;
      Filestream.Position:=0;
      AContext.Connection.IOHandler.Write(filestream,filestream.Size,true)
      end;
 
finally
FreeAndNil(FileStream);
end;
AContext.Connection.Disconnect;
 
end;
Memo1.Lines.Add('Połączenie od: '+AContext.Connection.Socket.Binding.PeerIP +' ; o godzinie: '+timetostr(now)+' ; Akcja: '+Akcja);
end;

Dodałem dodatkowo do komponentu IdTcpServer Bindings 0.0.0.0 port 3500 ( bo na takim działam) i zaznaczyłem IPv4

edytowany 1x, ostatnio: madmike, 2011-08-31 15:37

Pozostało 580 znaków

2011-08-31 14:00
0

1.KOD W [.CODE]

  1. "a raz wywala błąd o treści "raised exception class 'External: SIGSEGV'" pos stronie servera." - Naucz się używać debugera i powiedz GDZIE się wywala.

Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.
edytowany 1x, ostatnio: payl, 2011-08-31 14:01

Pozostało 580 znaków

2011-08-31 14:43
0

...Problem polega na tym, że debugując po stronie servera w Lazarusie błąd wywala na connect a dokładniej staje na...

gtk_text_view_scroll_to_iter(AStrings.FGtkText, @CursorIter, 0, False, 0, 0);

unit gtk2MemoStrings.inc

i dlatego nie jest to takie proste, podejrzewa, że może chodzić o wielowątkowość

Proszę o jakieś wskazówki. Wyczytałem że są różnice w programowaniu sieciowym pod linuxem i windowsem

Pozostało 580 znaków

2011-08-31 14:55
0

Wyczytałem że są różnice w programowaniu sieciowym pod linuxem i windowsem

Pod Indy10: raczej nie. Przecież chodzi o wielośrodowiskowość, przynajmniej na wiki Lazarusa nic o tym nie mówią.

Co do błędu, daj cały call stack ( rAlt + S ).

I Popraw do cholery pierwszy post, kod w [.code] .

i dlatego nie jest to takie proste, podejrzewa, że może chodzić o wielowątkowość

Tylko dlaczego nic się nie burzy pod Windowsem? I skąd masz takie podejrzenia?

EDIT: A głupoty [CIACH!], kod w <.code>


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.
edytowany 1x, ostatnio: payl, 2011-08-31 14:56

Pozostało 580 znaków

2011-08-31 19:43
Svenson
0

Przede wszystkim dziekuje za zainteresowanie. Przesylam kod w znacznikach ponizej. Teraz nie mam dostepu do błędu. Najlepsze jest to, ze pod Windowsem chodzi normalnie wysyla plik i druga funkcja go pobieram i wyswietlam i jest ok. Kod postawiony pod lazarusem (server). Raz zadziala, i jak wysylam np drugi plik jest ten blad. Wyłącze serwer i znow za 1 razem zadziala i dalej nie. Byc może nie zamyka poprzedniego watku, lub np gdzies ma w pamieci poprzednie zdarzenie, (przypuszczam). Moze czegos brakuje po odebraniu informacji na serwerze na koncu, a np Windows to ignorowal. Moze masz np lepszy kod do socketów. Jestem poczatkujący i prosze o rady. Bład podesle jutro

 
//Po stronie Clienta
 
Function TSocketF.WyslijSocketem(PlikISciezka:string):integer;
var
fileStream: TFileStream;
ch:integer;
begin
ch:=0;
PolaczZServerem();
 
fileStream := TFileStream.Create(PlikISciezka, fmOpenRead or fmShareDenyWrite);
try
  try
  USocket.SocketF.Client.IOHandler.writeln('SFILE');
  USocket.SocketF.Client.IOHandler.writeln(ExtractFilename(PlikISciezka));
  USocket.SocketF.Client.IOHandler.LargeStream:=true;
  Filestream.Position:=0;
  USocket.SocketF.Client.IOHandler.Write(filestream,filestream.Size,true);
 
  finally
  FreeAndNil(FileStream);
  end;
 
 except
 on E:Exception do
 begin
 glowny.ostrzezenie('Błąd wysyłania pliku');
 ch:=1;
 end;
 end;
 
 WyslijSocketem:=ch;
 end;
 
Procedure PolaczZServerem();
begin
try
//if USocket.SocketF.Client.Connected=true then
   USocket.SocketF.Client.Disconnect;
   USocket.SocketF.Client.IOHandler.Free;
 
   USocket.SocketF.Client.Host:=glowny.DaneFirmy(1).SERWER_HOST;
   USocket.SocketF.Client.Port:=glowny.DaneFirmy(1).SERWER_PORT;
   //USocket.SocketF.IdSSLIOHandlerSocketOpenSSL1.PassThrough:=false;
 
   USocket.SocketF.Client.Connect;
except
glowny.ostrzezenie('Problem z nawiązaniem połączenia z serwerem PBaza');
end;
end;
 
//PO STRONIE SERVERA
 
procedure TSocketF.ServerExecute(AContext: TIdContext);
var
Akcja,NazwaPliku,Katalog:string;
FileStream:TFileStream;
begin
  if not USocket.SocketF.Server.Active then
  begin
    USocket.SocketF.server.Active := true;
  end;
    Katalog:=ExtractFilePath(Application.ExeName)+'Pliki\';
 while AContext.Connection.Connected do
begin
try
  Akcja:=AContext.Connection.IOHandler.ReadLn;
      if Akcja='SFILE' then
      begin
      NazwaPliku:=AContext.Connection.IOHandler.ReadLn;
      FileStream := TFileStream.Create(Katalog+NazwaPliku, fmCreate);
      AContext.Connection.IOHandler.LargeStream:=true;
      AContext.Connection.IOHandler.ReadStream(FileStream, -1, False);
      end;
 
      if Akcja='GFILE' then
      begin
      NazwaPliku:=AContext.Connection.IOHandler.ReadLn;
      fileStream := TFileStream.Create(Katalog+NazwaPliku, fmOpenReadWrite);
      AContext.Connection.IOHandler.LargeStream:=true;
      Filestream.Position:=0;
      AContext.Connection.IOHandler.Write(filestream,filestream.Size,true)
      end;
 
finally
FreeAndNil(FileStream);
end;
AContext.Connection.Disconnect;
 
end;
Memo1.Lines.Add('Połączenie od: '+AContext.Connection.Socket.Binding.PeerIP +' ; o godzinie: '+timetostr(now)+' ; Akcja: '+Akcja);
end;
 

Pozostało 580 znaków

2011-08-31 20:51
0

Byc może nie zamyka poprzedniego watku, lub np gdzies ma w pamieci poprzednie zdarzenie, (przypuszczam).

To czemu dajesz kod połączenia?
Na problemy z wątkami (a dokładniej z pamięcią) masz przełącznik -gh (lub moduł heaptrc - to prawie to samo).

Może spróbuj z Lazarusem pod Windowsem i sprawdź czy nadal będą problemy, będziemy wiedzieć czy to wina środwiska czy OS.


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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