Einzelnen Beitrag anzeigen

backdraft

Registriert seit: 19. Apr 2005
Ort: Hückeswagen
335 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Daten per TCP/IP übertragen

  Alt 3. Dez 2008, 09:06
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
Oliver
  Mit Zitat antworten Zitat