Einzelnen Beitrag anzeigen

Benutzerbild von BlackJack
BlackJack

Registriert seit: 2. Jul 2005
Ort: Coesfeld
246 Beiträge
 
Delphi 2005 Personal
 
#1

Client/Serververbindung arbeitet kurz und friert dann ein.

  Alt 18. Jul 2006, 16:55
Moin,
ich habe ein paar Probleme mit einer Client-Server-Verbindung (mit TServerSocket & TClientSocket). Und zwar möchte ich mir einen Netzwerkrenderer für meinen Raytracer programmieren (spielt aber erstmal keine Rolle). Das ganze soll so ablaufen:
  • Der Client schickt ne Nachricht zum Server, das er gerne ne Aufgabe hätte ("givejob")
  • Der Server schickt einen Auftrag zum Client, was dieser tun soll ("dojob"),
  • Der Client macht, was er tun soll, d.h. er rechnet ein bisschen rum
  • Wenn er damit fertig ist, schickt der dem Server die Ergebnisse zurück ("donejob")
  • Der Server bestätig dem Client, dass die Ergebnisse angekommen sind ("datareceived")
  • Danach kann sich der Client n neuen Auftrag holen; wenn es nichts mehr zu tun gibt, anwortet der Server mit "nomorejobs"
Für das Übermittel der Nachrichten hab ich mir auch schön ein Protokoll ausgedacht: zuerst wird eine Signatur übermittelt ("lrt"), dann ein byte, das die Länge der nachfolgenden Zeichenkette angibt, und in der Zeichenkette stehen dann halt die "Auftragsstrings" drin (givejob, dojob etc.).

Im Prinzip funktioniert das ganze auch ansatzweise, allerdings kommt beim Server nach ein paar Aufträgen nichts mehr an. Und mit zwei Clients gleichzeitig kann der Server auch nicht arbeiten, dann friert er einfach so lange ein, bis einer der Clients wieder disconnected.

Meine Frage ist jetzt erstmal (da ich mich gerade erst in das Thema TCP/IP), ob ich überhaupt die Nachrichten und Daten zwischen Server richtig austausche; die entsprechenden Routinen stehen in der Unit TCPUtils.pas, aber ich poste sie trotzdem nochmal hier.

Desweiteren wolle ich mal fragen, wie man das am Besten mit der Fehlerbehandlung macht, weil teilweise der Server abstürzt, wenn ein Client disconnected etc.
Und dann natürlich noch die Frage, warum ein paar Aufträge bearbeitet werden und danach nichts mehr beim Server ankommt...

Ich hab einfach mal das gesamte Projekt in den Anhang gepackt.
Ach ja, bis jetzt ist das alles nur ein Testprojekt; das eigentliche Rechnen macht der TRenderThread in der Methode Execute(), da wird einfach ein Fraktal berechnet.

hier nochmal der Source der "Kommunikationsroutinen":

Delphi-Quellcode:
function SendData(ASocket: TCustomWinsocket; AData: Pointer; ASize: Integer;
  ATimeOut: Integer): Boolean;
  var send, tmp: Integer;
      time: Cardinal;
      PB: PByteArray;
  begin
  Result := False;
  if not ASocket.Connected then
    Exit;

  send := 0;
  time := GetTickCount;
  PB := AData;
  while send < ASize do
    begin
    tmp := ASocket.SendBuf(PB^[send], ASize-send);
    if tmp <> -1 then
      begin
      send := send + tmp;
      time := GetTickCount;
      end
    else
      if GetTickCount - time >= ATimeOut then
        Exit;
    if send <> ASize then
      Sleep(10);
    end;
  Result := True;
  end;

function ReceiveData(ASocket: TCustomWinsocket; AData: Pointer; ASize: Integer;
  ATimeOut: Integer): Boolean;
  var rec, tmp: Integer;
      time: Cardinal;
      PB: PByteArray;
  begin
  Result := False;
  if not ASocket.Connected then
    Exit;

  rec := 0;
  time := GetTickCount;
  PB := AData;
  while rec < ASize do
    begin
    tmp := ASocket.ReceiveBuf(PB^[rec], ASize - rec);
    if tmp <> -1 then
      begin
      rec := rec + tmp;
      time := GetTickCount;
      end
    else
      if GetTickCount - time >= ATimeOut then
        Exit;
    if rec <> ASize then
      Sleep(10);
    end;
  Result := True;
  end;

function ReceiveCommand(ASocket: TCustomWinSocket): string;
  var Sig: string;
      CommandLength: Byte;
      PB: PByteArray;
  begin
  Result := '';
  if ASocket.ReceiveLength < 4 then
    Exit;

  SetLength(Sig, 3);
  ReceiveData(ASocket, @Sig[1], 3);
  ReceiveData(ASocket, @CommandLength, 1);
  if Sig <> 'lrtthen
    Exit;

  SetLength(Result, CommandLength);
  ReceiveData(ASocket, @Result[1], CommandLength); {}
  end;

procedure SendCommand(ASocket: TCustomWinSocket; ACommand: string; AData: Pointer; ASize: Integer);
  var Data: string;
      l: Integer;
  begin
  Data := 'lrt' + Chr(Length(ACommand)) + ACommand;
  SendData(ASocket, @Data[1], Length(Data));
  if AData <> nil then
    SendData(ASocket, AData, ASize);
  end;
Ich bin für jede Hilfe dankbar.
Angehängte Dateien
Dateityp: zip distrubutedcomputing_151.zip (453,6 KB, 12x aufgerufen)
See my shadow changing, stretching up and over me.
Soften this old armor. Hoping I can clear the way
By stepping through my shadow, coming out the other side.
Step into the shadow. Forty six and two are just ahead of me.
  Mit Zitat antworten Zitat