Akni - Di 08.04.03 16:17
Titel: TclientSocket, TServerSocket in Blocking-Mode
Hallo,
ich schreibe jetzt eine C/S Anwendung, die über folgende Funktionalität verfügen soll:
1. nach der Herstellung der Verbindung sendet Server an den Client zyklisch ein Datensatz
2. Client kann ein Befehl an den Server senden;
3. Datenaustausch in beide Richtungen (bin noch nicht so weit).
Dafür verwende ich Standard Delphi-Komponenten TClientSocket, TServerSocket in ctBlocking-Mode.
Wenn Client und Server auf dem gleichen Rechner laufen, dann erfolgt nach der Herstellung der Verbindung den Datenaustausch sofort.
Wenn die aber auf unterschiedlichen PCs ausgeführt werden, dann dauert es zwischen Herstellung der Verbindung und der ersten Portion von Daten ca. 40sec.
D.h. auf dem Server tritt Ereignis ServerSocket.Accept gleich nachdem die Verbindung vom Client angefordert wurde, aber Datenübertragung vom Server Stream.Send(…) erfolgt erst in 30-40 sec.
Code für den Client:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77:
| procedure TISClientThread.Execute; var Stream: TWinSocketStream;
SizeOfBuffer: integer; Size1: integer; iCode: integer; iREcvdCode: integer; str1: string; begin { Thread-Code hier plazieren } try
fClientSocket:=TClientSocket.Create(nil); fActionCode:=0;
try fClientSocket.Address := ServerAddress; fClientSocket.Port := ServerPort; fClientSocket.ClientType := ctBlocking; Stream := TWinSocketStream.Create(fClientSocket.Socket, iTimeOut); fLogStr:='ClientThread.Execute: ServerAddress = '+fClientSocket.Address+ ' ServerPort = '+IntToStr(fClientSocket.Port); Synchronize(WrLog); fClientSocket.Active := True;
//Verbindung hergestellt, Formular anzeigen PostMessage(fFormHandle,wm_ShowForm,0,0);
while (not Terminated) and (fClientSocket.Active) do begin
if fActionCode<>0 then begin iCode:=cdACTION; Stream.Write(iCode, SizeOf(iCode)); Stream.Write(fActionCode, SizeOF(fActionCode)); fActionCode:=0; end;
// if Stream.WaitForData(2000) then // begin if (not Terminated) and (fClientSocket.Active) then begin SizeOfBuffer:=Stream.Read(iRecvdCode, sizeOf(iRecvdCode)); //zuerst wird immer iCode gesendet if SizeOfBuffer>0 then begin //Daten lesen case iRecvdCode of cdREC: begin Stream.Read(GlobalRcvdDat,sizeOf(GlobalRcvdDat)); PostMessage(fFormHandle,wm_RefreshClients,cdREC,0); iCode:=cdOK; Stream.Write(iCode, SizeOf(iCode)); //Bestätigung zurück senden end; end; end;
end //if not terminated end; finally fClientSocket.Active := False; fClientSocket.Free; Stream.Free; end; except on E: Exception do begin fLogStr:=E.Message; Synchronize(WrLog); fClientSocket.Close; Terminate; PostMessage(fFormHandle,wm_CanNotConnect,0,0); end; end; end; |
für den Server:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
| procedure TISServerThread.ClientExecute; var Stream: TWinSocketStream; str: string;
SizeOfBuffer: integer; iCode: Integer; iRecvdCode: integer; iActionCode: integer; begin fLastSend:=Now;
inherited FreeOnTerminate:=true; try Stream:=TWinSocketStream.Create(ClientSocket, iTimeOut); fLogStr:='Client Execute'; Synchronize(WrLog); try while (not Terminated) and ClientSocket.Connected do begin
//Datenstructur senden, falls neue Daten vorhanden sind EnterCriticalSection(CriticalSection); if DataReady then begin if ClientSocket.Connected then begin iCode:=cdRec; Stream.Write(iCode, sizeOf(iCode)); Stream.Write(GlobalDat, SizeOF(GlobalDat));
fLastSend:=Now; fLogStr:='Daten gesendet!!'; Synchronize(WrLog); end; DataReady:=False; end; LeaveCriticalSection(CriticalSection);
//aus dem Stream lesen if Stream.WaitForData(200) then begin
SizeOfBuffer:=Stream.Read(iRecvdCode,sizeOf(iRecvdCode));
if SizeOfBuffer>0 then begin //abhängig vom iCode bestimmte Aktionen durchführen case iRecvdCode of cdOK: begin Stream.Write(iRecvdCode, sizeOf(iRecvdCode)); fLogStr:='Bestätigung bekommen!!'; Synchronize(WrLog); end; cdACTION: begin Stream.Read(iActionCode,sizeOf(iActionCode)); fLogStr:='ActionCode = '+IntToStr(iActionCode); Synchronize(WrLog); case iActionCode of cdBUTTON: PostMessage(fFormHandle,wm_RefreshClients,iActionCode,0); end; end; end;//select end; end //WaitForData else begin //ClientSocket.Close; fLogStr:='No Data'; Synchronize(WrLog); end; end; finally Stream.Free; end; except on E: Exception do begin fLogStr:=E.Message; Synchronize(WrLog); ClientSocket.Close; Terminate; end; end; end; |
Könnte mir jemand einen Tipp geben, woran es liegt und wie ich das Problem lösen kann?