Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Daten per TCP/IP übertragen (https://www.delphipraxis.net/125225-daten-per-tcp-ip-uebertragen.html)

backdraft 2. Dez 2008 21:32


Daten per TCP/IP übertragen
 
Hallo zusammen,
ich hab mittlerweile schon vieles probiert, aber irgendwie knallt alles immer. In manchen Threads ließt man, die Komponenten sind mist, in anderen das andere Mist sind.

Ich suche eigentlich eine Möglichkeit für einen kleinen TCP-IP Server und Client.

Ein Client soll einen Connect auf einen Server machen und dann Daten dahin verschicken.
Der Server soll die Daten einfach annehmen. Zusätzlich soll der Server auch an das Client Daten schicken können.
Das Client ist eine Consolenanwendung.

Soweit, ... soeinfach...

Spätestens, wenn mein Client anfängt sehr schnell, viele Daten zu schicken, knallt es.
Es scheint es so zu sein, als wenn der Send Befehl vom TCPClient sofort zurückkommt, ohne das er die Daten schon übertragen hat.
Mache ich das jetzt 100 mal, dann kommt die Meldung "Buffer voll".
Ein Sleep(1000) behebt das Problem lokal, aber wohl kaum im Netz.

Ich habe wirklich schon viele Sachen ausprobiert, aber nix klappt. Bei manchen knallt es, sobald ein zweiten Client connected, andere knallen sofort.

Ich hätte am liebsten was ohne irgendwelche Komponenten, direkt auf der winsock2 basierend.
Hat jemand ein vlt sowas schonmal gemacht, oder ein HowTo?

Vielen Dank für jeden Tip.
Oliver

mkinzler 2. Dez 2008 21:36

Re: Daten per TCP/IP übertragen
 
Schau dir mal Synapse an

inherited 2. Dez 2008 23:20

Re: Daten per TCP/IP übertragen
 
Wie sendest/empfängst du denn?

WS1976 3. Dez 2008 06:49

Re: Daten per TCP/IP übertragen
 
Hallo,

wenns schon "knallt" dann solltest du uns wenigstens ein bisschen Anteil haben lassen an deinem Feuerwerk.
Glaubst du im ernst dass dir jemand helfen kann wenn du nur mitteilst "es knallt".
Also: wo ist dein Sourcecode? Wie versuchst du Daten zu übertragen? Wie ist die Fehlermeldung? Was geht eigentlich schief?

Grüsse
Rainer

backdraft 3. Dez 2008 09:06

Re: Daten per TCP/IP übertragen
 
Zitat:

Zitat von WS1976
Hallo,

wenns schon "knallt" dann solltest du uns wenigstens ein bisschen Anteil haben lassen an deinem Feuerwerk.
Glaubst du im ernst dass dir jemand helfen kann wenn du nur mitteilst "es knallt".
Also: wo ist dein Sourcecode? Wie versuchst du Daten zu übertragen? Wie ist die Fehlermeldung? Was geht eigentlich schief?

Grüsse
Rainer

Speicherzugriffsfehler, System out of resource. Wenn ich den Fehler beschreiben könnte, oder wüsste wo er her kommt, hätte ich das schon gemacht.
Ich hab auch nix zur Zeit was überhaupt noch funktioniert. Da ich mitterweile so viel probiert habe, und alles ging schief, bin ich auf der Suche nach einem HowTo, wie man es richtig macht. Wenns dann noch immer "knallt" poste ich bestimmt auch den Code.

Mir fehlt halt das wie und das warum es so funktioniert. Das mit dem Senden hat eigentlich immer funktioniert, aber das Empfangen halt nicht.

Die Client Sende funktion sieht so aus:
Delphi-Quellcode:
function TiBTcpClient.Send(const ABuffer; ALength: Integer): Integer;
var
  LSent: Integer;
  LCount: Integer;
  LLeft: Integer;
  LBuffer: Pointer;
begin

  if not FConnected then raise Exception.Create('iBNoConnectionError');

  LSent := 0;
  LLeft := ALength;
  try

    while LSent < ALength do begin
      LBuffer := Pointer(Integer(Pointer(@ABuffer)) + LSent);
      LCount := WinSock2.Send(FSocket, LBuffer^, LLeft, 0);
      if LCount = SOCKET_ERROR then RaiseLastSocketError;

      LSent := LSent + LCount;
      LLeft := ALength - LSent;
    end;
  except
    Reset;
    raise;
  end;
  Result := LSent;
end;
Die WinSock2.pas ist eine Umsetzung der Jedis aus dem Jahr 2000 von der Winsock.h.

Zum Senden des Pakets habe ich mir eine Funktion geschrieben:
Delphi-Quellcode:
function TiBTcpClient.SendStream(aStream: TStream; aSize: Integer): Integer;
var vMem: TiBMemoryStream;
begin
  vMem := TiBMemoryStream.Create;
  try
    vMem.WriteCardinal(1);
    vMem.WriteCardinal(aSize);
    vMem.CopyFrom(aStream, aSize);
    result := Send(vMem.Memory^, vMem.Size);
  finally
    vMem.Free;
  end;
end;
Empfangen tu ich das ganze mit den Indy Tools via:
Delphi-Quellcode:
procedure TMainUnit.IdTCPServer1Execute(AContext: TIdContext);

type
  TPacketHeader = packed record
    PacketType: Cardinal;
    PacketSize: Cardinal;
  end;

const
  cBuffSize = 1024;

var
  vPacketHeader: TPacketHeader;
  vBytesToRead: Cardinal;
  LBuffer: Pointer;
  vBuffer: TBytes;
  vData: TiBMemoryStream;

begin

  // Copy packet header
  vPacketHeader.PacketType := AContext.Connection.Socket.ReadCardinal(False);
  vPacketHeader.PacketSize := AContext.Connection.Socket.ReadCardinal(False);

  // Copy packet body
  vData := TiBMemoryStream.Create;

  while vPacketHeader.PacketSize > 0 do
    begin
      if vPacketHeader.PacketSize > cBuffSize then
        vBytesToRead := cBuffSize
      else
        vBytesToRead := vPacketHeader.PacketSize;

      AContext.Connection.Socket.ReadBytes(vBuffer, vBytesToRead, False);
      vData.Write(vBuffer[0], vBytesToRead);
      Dec(vPacketHeader.PacketSize, vBytesToRead);
   end;

   vData.Position := 0;

   // Verarbeite Block ...

   vData.Free;

  // Write tcp answer
  vBuffer := RawToBytes('OK', Length('OK'));
  AContext.Connection.Socket.Write(vBuffer);

end;
Teilweise kommen System out of resource Meldungen, dann gehts wieder. Meistens hängt das Programm aber beim Execute.
Ich denke ich mache da irgendwas total falsch.

Ich mach mal eine Liste von Fragen, mit den Antworten komme ich bestimmt schon weiter.
- Ist es normal, dass der Winsock.Send immer sofort zurückkommt?
- Wenn ja, wie löse ich das Problem, dass nach kurzer Zeit der Speicher voll ist?
- Was heisst Blocking/Non-Blocking?
- Muss die TCP-Server/Client Verbindung als Thread laufen? Im Server und/oder im Client?
- Muss ich einen Stream von 1MB, den ich verschicken will, selbst zerlegen, oder kann ich ihn direkt senden?
- Kommen die Pakete in der richtigen Reihenfolge auf dem Server an, oder muss ich dafür auch was tun?
- Wie unterscheide ich die einzelnen Clients?

mfg Oliver

Sherlock 3. Dez 2008 09:15

Re: Daten per TCP/IP übertragen
 
1) Wenn Du schon die Indys zum Empfangen verwendest, warum nicht auch zum Senden?
2) Dann dürfte sich alles andere von selbst erledigen ;)

Sherlock

backdraft 3. Dez 2008 09:34

Re: Daten per TCP/IP übertragen
 
Zitat:

Zitat von Sherlock
1) Wenn Du schon die Indys zum Empfangen verwendest, warum nicht auch zum Senden?
2) Dann dürfte sich alles andere von selbst erledigen ;)

Sherlock

Weil es eine Consolenanwendung ist, die in Delphi 3+5 kompiliert wird. Da gehen die Indys nicht. Davon ab, hab ich damit unter D2007 auch nicht hinbekommen. Und nach allen Meinungen im Netz, sollte man lieber selbst was auf WinSock2 aufbauen.
Hab ich ja im Client Bereich auch schon ein wenig geschafft.

Sherlock 3. Dez 2008 09:53

Re: Daten per TCP/IP übertragen
 
Ich sehe nicht ein, das Rad immer wieder neu erfinden zu müssen! Vor allem die Komponenten sind das, was Delphi angenehm von der grauen Masse unterscheidet. Die ICS von Francois Piette funktioniert von Delphi 1 an aufwärts.

Natürlich werden die NonVCL Puristen aufschreien, aber denen kann ich nur ein gepflegtes "Warum habt Ihr dann Delphi gekauft?" entgegnen. ;)

Viel Spaß!

Sherlock

backdraft 3. Dez 2008 09:58

Re: Daten per TCP/IP übertragen
 
Zitat:

Zitat von Sherlock
Ich sehe nicht ein, das Rad immer wieder neu erfinden zu müssen! Vor allem die Komponenten sind das, was Delphi angenehm von der grauen Masse unterscheidet. Die ICS von Francois Piette funktioniert von Delphi 1 an aufwärts.

Natürlich werden die NonVCL Puristen aufschreien, aber denen kann ich nur ein gepflegtes "Warum habt Ihr dann Delphi gekauft?" entgegnen. ;)

Viel Spaß!

Sherlock

OK, hast du denn eine Doku wie man ganz simpel mit Indy oder ICS einen Stream von A nach B überträgt? Mit Rückmeldung das es angekommen ist?

mkinzler 3. Dez 2008 10:10

Re: Daten per TCP/IP übertragen
 
Hast du dir mal die Beispeile zu ICS angesehen? Vorallem das TnSrv Bsp sollte doch passend sein


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:40 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz