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 <> 'lrt' then
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.
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.