Delphi + Lazarus + Socket

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

0

1.KOD W [.CODE]
2. "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.

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

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>

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;
 
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.

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