Autor Beitrag
Akni
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Di 08.04.03 16:17 
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:

ausblenden volle Höhe 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:
ausblenden volle Höhe 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?