Entwickler-Ecke

Internet / Netzwerk - Socket in einem Thread


Akni - Di 22.04.03 17:05
Titel: Socket in einem Thread
Hallo,
könnte mir jemand bei so einem Problem helfen:

ich muß nicht blockierende TClientSocket, TServerSocket - Komponente in einem Thread erstellen und verwalten.

Ich definiere socket-Komponente als private-Feld im Thread, erstelle Socket in der Prozedure Execute und definiere auch ensprechende Socket-Ereignisse (OnRead, OnConnect,..).

Die Frage ist, wie ich jetzt diese Ereignisse mit der Methode Execute verbinden kann? was soll ich in der Schleife

while not Terminated do
begin
....
end;

schreiben?



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:
TISServerThread = class(TThread)
  private
    { Private-Deklarationen }
    fLogStr: string;
    fLog: TISLog;
    fOwner: TComponent;
    fServerSocket: TServerSocket;
    procedure SocketAccept(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketWrite(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketListen(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketError(Sender: TObject; Socket: TCustomWinSocket;
        ErrorEvent: TErrorEvent;  var ErrorCode: Integer);
    procedure SocketClientConnect(Sender: TObject;
        Socket: TCustomWinSocket);
    procedure SocketClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure WrLog;
  protected
    procedure Execute; override;
  public
    constructor Create(Own: TComponent; Log: TISLog);
  end;

constructor TISServerThread.Create;
begin
  fLog:=Log;
  fOwner:=Own;

  FreeOnTerminate:=true;
  inherited Create(false);

  fLogStr:='ServerThread Created';
  Synchronize(WrLog);
end;

procedure TISServerThread.Execute;
begin

  fServerSocket:=TServerSocket.Create(fOwner);
  fServerSocket.ServerType:=stNonBlocking;
  fServerSocket.OnAccept:=SocketAccept;
  fServerSocket.OnClientDisconnect:=SocketClientDisconnect;
  fServerSocket.OnClientConnect:=SocketClientConnect;
  fServerSocket.OnClientRead:=SocketRead;
  fServerSocket.OnListen:=SocketListen;
  fServerSocket.OnClientError:=SocketError;
  fServerSocket.Port:=PortNr;
  fServerSocket.Active:=true;

  while not Terminated do
  begin
    //und was soll man hier schreiben????
  end;
end;


MSCH - Di 22.04.03 17:29

ganz einfach, eine Endlosschleife:


Quelltext
1:
while not terminated do ;                    

fertig. alles
grez
msch

Moderiert von user profile iconTino: Code-Tags hinzugefügt.


Akni - Di 22.04.03 22:29

So einfach ist es nicht. Da muß man mind. in der Schleife Application.ProcessMessages schreiben, sonst empfängt Tread auch die Socket-Ereignisse nicht.

Und das ist, meine Meinung nach, auch keine gute Lösung, weil der Thread dann immer aktiv ist 100% CPU-Zeit verbraucht.

Hat jemand vielleicht andere Ideen?


focus - Mi 23.04.03 09:06

wenn ich dich richtig verstanden habe willst du aus deinem hauptprogramm dem thread z.b. sagen: fange senden an, beende dich,usw..
schau dich mal nach waitformultipleobjects und waitforsingleobject um damit legst dueinen thread bis zum eintreten eines events schlafen...
gruss
michael


MSCH - Mi 23.04.03 17:00

In einem thread ProcessMessages aufrufen ist grütze. Der Thread erhält seine Zeit von dem BS! Und wenn der die Prio tpIdle hat, läuft er eh nur, wenn nix anderes ansteht.
grez
msch


focus - Do 24.04.03 08:19

@MSCH
wen meinst du?


Akni - Do 24.04.03 09:01

jetzt weiss ich, wie man es richtig macht:

in der while not terminated do... Schleife muß man Windows-Botschaften mit PeekMessage(...), DipatchMessage(...) verarbeiten. Dann reagiert Thread auf Socket-Ereignisse und verbraucht keine zusätzliche CPU-Zeit


MSCH - Do 24.04.03 17:31

@Focus: ich meine niemanden, sondern in einem Thread Proccessmessage() oder die äquivalente PeekMessage() und Dispatchmessage() aufzurufen.
Dann kann ich das nämlich auch direkt als Procedure meiner Anwendung deklarieren oder in einem Timer.

grez.
msch