看看帮助啊 Threads for server connections are descendants of TServerSocketThread. Because of this, you can抰 use the New Thread object dialog. Instead, declare your thread manually as follows: TMyServerThread = class(TServerClientThread);To implement this thread, you override the ClientExecute method instead of the Execute method. Implementing the ClientExecute method is much the same as writing the Execute method of the thread for a client connection. However, instead of using a client socket component that you place in your application from the Component palette, the server client thread must use the TTcpClient object that is created when the listening server socket accepts a client connection. This is available as the public ClientSocket property. In addition, you can use the protected HandleException method rather than writing your own thread-safe exception handling. For example:procedure TMyServerThread.ClientExecute;var Stream : TWinSocketStream; Buffer : array[0 .. 9] of Char; begin { make sure connection is active } while (not Terminated) and ClientSocket.Connected do begin try Stream := TWinSocketStream.Create(ClientSocket, 60000); try FillChar(Buffer, 10, 0); { initialize the buffer } { give the client 60 seconds to start writing } if Stream.WaitForData(60000) then begin if Stream.Read(Buffer, 10) = 0 then { if can't read in 60 seconds } ClientSocket.Close; { close the connection } { now process the request } ... end else ClientSocket.Close; { if client doesn't start, close } finally Stream.Free; end; except HandleException; end; end; end;Warning: Server sockets cache the threads they use. Be sure the ClientExecute method performs any necessary initialization so that there are no adverse results from changes made when the thread last executed.To use your thread, create it in an OnGetThread event handler. When creating the thread, set the CreateSuspended parameter to False. To write a thread for client connections, define a new thread object using the New Thread Object dialog. The Execute method of your new thread object handles the details of reading and writing over the thread connection. It creates a TWinSocketStream object, and uses that to read or write. For example:procedure TMyClientThread.Execute;var TheStream: TWinSocketStream; buffer: string; begin { create a TWinSocketStream for reading and writing } TheStream := TWinSocketStream.Create(ClientSocket1.Socket, 60000); try { fetch and process commands until the connection or thread is terminated } while (not Terminated) and (ClientSocket1.Active) do begin try GetNextRequest(buffer); { GetNextRequest must be a thread-safe method } { write the request to the server } TheStream.Write(buffer, Length(buffer) + 1); { continue the communication (e.g. read a response from the server) } ... except if not(ExceptObject is EAbort) then Synchronize(HandleThreadException); { you must write HandleThreadException } end; end; finally TheStream.free; end; end;To use your thread, create it in an OnConnect event handler. For more information about creating and running threads, see Executing thread objects.
Unit main;InterfaceUses Windows, SysUtils, Messages, Classes, Forms, ScktComp, Controls, StdCtrls, Menus, Mask, Spin, ComCtrls, ExtCtrls;Const CM_IncCount = WM_USER + 1;Type TForm1 = Class(TForm) ServerSocket: TServerSocket; MainMenu: TMainMenu; File1: TMenuItem; ActiveItem: TMenuItem; N1: TMenuItem; Exit1: TMenuItem; Panel1: TPanel; Label1: TLabel; CacheEdit: TSpinEdit; Label2: TLabel; PortEdit: TSpinEdit; Label3: TLabel; ThreadCount: TEdit; Panel2: TPanel; ListBox1: TListBox; Panel3: TPanel; StatusBar1: TStatusBar; CharCount: TLabel; Procedure ServerSocketGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; Var SocketThread: TServerClientThread); Procedure FormCreate(Sender: TObject); Procedure FormClose(Sender: TObject; Var Action: TCloseAction); Procedure Exit1Click(Sender: TObject); Procedure PortEditChange(Sender: TObject); Procedure ActiveItemClick(Sender: TObject); Procedure ServerSocketThreadEnd(Sender: TObject; Thread: TServerClientThread); Procedure ServerSocketThreadStart(Sender: TObject; Thread: TServerClientThread); Procedure CacheEditChange(Sender: TObject); protected Procedure CMIncCount(Var Msg: TMessage); message CM_IncCount; public End;{ TFileServerThread } TFileServerThread = Class(TServerClientThread) public Procedure ClientExecute; override; End;Var Form1: TForm1;Implementation{$R *.DFM}{ TFileServerThread }Procedure TFileServerThread.ClientExecute; Var Data: Array[0..1023] Of char; RecText: String; SocketStream: TWinSocketStream; Begin While Not Terminated And ClientSocket.Connected Do Try SocketStream := TWinSocketStream.Create(ClientSocket, 30000); Try FillChar(Data, SizeOf(Data), 0); If SocketStream.Read(Data, SizeOf(Data)) = 0 Then Begin // If we didn't get any data after xx seconds then close the connection ClientSocket.SendText('Timeout on Server'+#13#10); //Wait a little time to allow sending of text before disconnect sleep(1); ClientSocket.Close; Terminate; End; RecText := Data; If Length(RecText) > 2 Then Delete(RecText, Pos(#13#10, RecText), 2); // Delete #13#10 If ClientSocket.Connected Then Begin ClientSocket.SendText(RecText); SendMessage(Form1.Listbox1.Handle, LB_ADDSTRING, 0, Integer(PChar(RecText))); PostMessage(Form1.Handle, CM_INCCOUNT, 0, 0); End; Finally SocketStream.Free; End; Except HandleException; End; End;Procedure TForm1.ServerSocketGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; Var SocketThread: TServerClientThread); Begin // Create a new thread for connection SocketThread := TFileServerThread.Create(False, ClientSocket); ClientSocket.SendText('Welcome to Server'+#13#10); End;Procedure TForm1.FormCreate(Sender: TObject); Begin CacheEdit.Value := ServerSocket.ThreadCacheSize; PortEdit.Value := ServerSocket.Port; CharCount.Caption := '0'; ActiveItemClick(Nil); End;Procedure TForm1.FormClose(Sender: TObject; Var Action: TCloseAction); Begin ServerSocket.Close; End;Procedure TForm1.CMIncCount(Var Msg: TMessage); Begin CharCount.Caption := IntToStr(StrToInt(CharCount.Caption) + 1); End;Procedure TForm1.Exit1Click(Sender: TObject); Begin Close; End;Procedure TForm1.PortEditChange(Sender: TObject); Begin ServerSocket.Port := StrToInt(PortEdit.Text); End;Procedure TForm1.ActiveItemClick(Sender: TObject); Begin ServerSocket.Active := Not ServerSocket.Active; ActiveItem.Checked := ServerSocket.Active; If ServerSocket.Active Then StatusBar1.SimpleText := 'Active' Else StatusBar1.SimpleText := 'InActive'; End;Procedure TForm1.ServerSocketThreadEnd(Sender: TObject; Thread: TServerClientThread); Begin ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) - 1); End;Procedure TForm1.ServerSocketThreadStart(Sender: TObject; Thread: TServerClientThread); Begin ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) + 1); End;Procedure TForm1.CacheEditChange(Sender: TObject); Begin ServerSocket.ThreadCacheSize := CacheEdit.Value; End;End.//////////////////// object Form1: TForm1 Left = 720 Top = 130 Width = 399 Height = 262 Caption = 'Server' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] Menu = MainMenu OldCreateOrder = True OnClose = FormClose OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object Panel1: TPanel Left = 0 Top = 0 Width = 120 Height = 197 Align = alLeft BevelOuter = bvNone TabOrder = 0 object Label1: TLabel Left = 8 Top = 5 Width = 94 Height = 13 Caption = 'Thread Cache Size:' end object Label2: TLabel Left = 10 Top = 50 Width = 22 Height = 13 Caption = 'Port:' end object Label3: TLabel Left = 10 Top = 91 Width = 65 Height = 13 Caption = 'Thread Count' end object CacheEdit: TSpinEdit Left = 9 Top = 22 Width = 61 Height = 22 MaxValue = 20 MinValue = -1 TabOrder = 0 Value = 0 OnChange = CacheEditChange end object PortEdit: TSpinEdit Left = 8 Top = 64 Width = 60 Height = 22 MaxLength = 4 MaxValue = 9000 MinValue = 1 TabOrder = 1 Value = 1 OnChange = PortEditChange end object ThreadCount: TEdit Left = 8 Top = 107 Width = 62 Height = 21 Color = clBtnFace ReadOnly = True TabOrder = 2 Text = '0' end end object Panel2: TPanel Left = 120 Top = 0 Width = 271 Height = 197 Align = alClient BevelOuter = bvNone Caption = 'Panel2' TabOrder = 1 object ListBox1: TListBox Left = 0 Top = 21 Width = 271 Height = 176 Align = alClient ItemHeight = 13 TabOrder = 0 end object Panel3: TPanel Left = 0 Top = 0 Width = 271 Height = 21 Align = alTop Alignment = taLeftJustify BevelOuter = bvNone Caption = 'Chars Sent:' TabOrder = 1 object CharCount: TLabel Left = 55 Top = 4 Width = 50 Height = 13 Caption = 'CharCount' end end end object StatusBar1: TStatusBar Left = 0 Top = 197 Width = 391 Height = 19 Panels = <> SimplePanel = True end object ServerSocket: TServerSocket Active = False Port = 1024 ServerType = stThreadBlocking OnGetThread = ServerSocketGetThread OnThreadStart = ServerSocketThreadStart OnThreadEnd = ServerSocketThreadEnd Left = 315 Top = 1 end object MainMenu: TMainMenu Left = 350 Top = 1 object File1: TMenuItem Caption = '&Server' object ActiveItem: TMenuItem Caption = '&Active' OnClick = ActiveItemClick end object N1: TMenuItem Caption = '-' end object Exit1: TMenuItem Caption = 'E&xit' OnClick = Exit1Click end end end end////////////////////////////program server;uses Forms, main in 'main.pas' {Form1};{$R *.RES}begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.对你应该有用。
能不能也给我一份,多谢
[email protected]
Threads for server connections are descendants of TServerSocketThread. Because of this, you can抰 use the New Thread object dialog. Instead, declare your thread manually as follows: TMyServerThread = class(TServerClientThread);To implement this thread, you override the ClientExecute method instead of the Execute method.
Implementing the ClientExecute method is much the same as writing the Execute method of the thread for a client connection. However, instead of using a client socket component that you place in your application from the Component palette, the server client thread must use the TTcpClient object that is created when the listening server socket accepts a client connection. This is available as the public ClientSocket property. In addition, you can use the protected HandleException method rather than writing your own thread-safe exception handling. For example:procedure TMyServerThread.ClientExecute;var
Stream : TWinSocketStream;
Buffer : array[0 .. 9] of Char;
begin
{ make sure connection is active }
while (not Terminated) and ClientSocket.Connected do
begin
try
Stream := TWinSocketStream.Create(ClientSocket, 60000);
try
FillChar(Buffer, 10, 0); { initialize the buffer }
{ give the client 60 seconds to start writing }
if Stream.WaitForData(60000) then begin
if Stream.Read(Buffer, 10) = 0 then { if can't read in 60 seconds }
ClientSocket.Close; { close the connection }
{ now process the request }
...
end
else
ClientSocket.Close; { if client doesn't start, close }
finally
Stream.Free;
end;
except
HandleException;
end; end;
end;Warning: Server sockets cache the threads they use. Be sure the ClientExecute method performs any necessary initialization so that there are no adverse results from changes made when the thread last executed.To use your thread, create it in an OnGetThread event handler. When creating the thread, set the CreateSuspended parameter to False.
To write a thread for client connections, define a new thread object using the New Thread Object dialog. The Execute method of your new thread object handles the details of reading and writing over the thread connection. It creates a TWinSocketStream object, and uses that to read or write. For example:procedure TMyClientThread.Execute;var
TheStream: TWinSocketStream;
buffer: string;
begin
{ create a TWinSocketStream for reading and writing }
TheStream := TWinSocketStream.Create(ClientSocket1.Socket, 60000);
try
{ fetch and process commands until the connection or thread is terminated }
while (not Terminated) and (ClientSocket1.Active) do
begin
try
GetNextRequest(buffer); { GetNextRequest must be a thread-safe method } { write the request to the server }
TheStream.Write(buffer, Length(buffer) + 1);
{ continue the communication (e.g. read a response from the server) }
...
except
if not(ExceptObject is EAbort) then
Synchronize(HandleThreadException); { you must write HandleThreadException }
end;
end;
finally
TheStream.free;
end;
end;To use your thread, create it in an OnConnect event handler. For more information about creating and running threads, see Executing thread objects.
Windows, SysUtils, Messages, Classes, Forms, ScktComp, Controls, StdCtrls,
Menus, Mask, Spin, ComCtrls, ExtCtrls;Const
CM_IncCount = WM_USER + 1;Type
TForm1 = Class(TForm)
ServerSocket: TServerSocket;
MainMenu: TMainMenu;
File1: TMenuItem;
ActiveItem: TMenuItem;
N1: TMenuItem;
Exit1: TMenuItem;
Panel1: TPanel;
Label1: TLabel;
CacheEdit: TSpinEdit;
Label2: TLabel;
PortEdit: TSpinEdit;
Label3: TLabel;
ThreadCount: TEdit;
Panel2: TPanel;
ListBox1: TListBox;
Panel3: TPanel;
StatusBar1: TStatusBar;
CharCount: TLabel;
Procedure ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
Var SocketThread: TServerClientThread);
Procedure FormCreate(Sender: TObject);
Procedure FormClose(Sender: TObject; Var Action: TCloseAction);
Procedure Exit1Click(Sender: TObject);
Procedure PortEditChange(Sender: TObject);
Procedure ActiveItemClick(Sender: TObject);
Procedure ServerSocketThreadEnd(Sender: TObject;
Thread: TServerClientThread);
Procedure ServerSocketThreadStart(Sender: TObject;
Thread: TServerClientThread);
Procedure CacheEditChange(Sender: TObject);
protected
Procedure CMIncCount(Var Msg: TMessage); message CM_IncCount;
public
End;{ TFileServerThread } TFileServerThread = Class(TServerClientThread)
public
Procedure ClientExecute; override;
End;Var
Form1: TForm1;Implementation{$R *.DFM}{ TFileServerThread }Procedure TFileServerThread.ClientExecute;
Var
Data: Array[0..1023] Of char;
RecText: String;
SocketStream: TWinSocketStream;
Begin
While Not Terminated And ClientSocket.Connected Do
Try
SocketStream := TWinSocketStream.Create(ClientSocket, 30000);
Try
FillChar(Data, SizeOf(Data), 0);
If SocketStream.Read(Data, SizeOf(Data)) = 0 Then
Begin
// If we didn't get any data after xx seconds then close the connection
ClientSocket.SendText('Timeout on Server'+#13#10);
//Wait a little time to allow sending of text before disconnect
sleep(1);
ClientSocket.Close;
Terminate;
End;
RecText := Data;
If Length(RecText) > 2 Then
Delete(RecText, Pos(#13#10, RecText), 2); // Delete #13#10
If ClientSocket.Connected Then
Begin
ClientSocket.SendText(RecText);
SendMessage(Form1.Listbox1.Handle, LB_ADDSTRING, 0, Integer(PChar(RecText)));
PostMessage(Form1.Handle, CM_INCCOUNT, 0, 0);
End;
Finally
SocketStream.Free;
End;
Except
HandleException;
End;
End;Procedure TForm1.ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
Var SocketThread: TServerClientThread);
Begin
// Create a new thread for connection
SocketThread := TFileServerThread.Create(False, ClientSocket);
ClientSocket.SendText('Welcome to Server'+#13#10);
End;Procedure TForm1.FormCreate(Sender: TObject);
Begin
CacheEdit.Value := ServerSocket.ThreadCacheSize;
PortEdit.Value := ServerSocket.Port;
CharCount.Caption := '0';
ActiveItemClick(Nil);
End;Procedure TForm1.FormClose(Sender: TObject; Var Action: TCloseAction);
Begin
ServerSocket.Close;
End;Procedure TForm1.CMIncCount(Var Msg: TMessage);
Begin
CharCount.Caption := IntToStr(StrToInt(CharCount.Caption) + 1);
End;Procedure TForm1.Exit1Click(Sender: TObject);
Begin
Close;
End;Procedure TForm1.PortEditChange(Sender: TObject);
Begin
ServerSocket.Port := StrToInt(PortEdit.Text);
End;Procedure TForm1.ActiveItemClick(Sender: TObject);
Begin
ServerSocket.Active := Not ServerSocket.Active;
ActiveItem.Checked := ServerSocket.Active;
If ServerSocket.Active Then
StatusBar1.SimpleText := 'Active'
Else
StatusBar1.SimpleText := 'InActive';
End;Procedure TForm1.ServerSocketThreadEnd(Sender: TObject;
Thread: TServerClientThread);
Begin
ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) - 1);
End;Procedure TForm1.ServerSocketThreadStart(Sender: TObject;
Thread: TServerClientThread);
Begin
ThreadCount.Text := IntToStr(StrToInt(ThreadCount.Text) + 1);
End;Procedure TForm1.CacheEditChange(Sender: TObject);
Begin
ServerSocket.ThreadCacheSize := CacheEdit.Value;
End;End.////////////////////
object Form1: TForm1
Left = 720
Top = 130
Width = 399
Height = 262
Caption = 'Server'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
Menu = MainMenu
OldCreateOrder = True
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 120
Height = 197
Align = alLeft
BevelOuter = bvNone
TabOrder = 0
object Label1: TLabel
Left = 8
Top = 5
Width = 94
Height = 13
Caption = 'Thread Cache Size:'
end
object Label2: TLabel
Left = 10
Top = 50
Width = 22
Height = 13
Caption = 'Port:'
end
object Label3: TLabel
Left = 10
Top = 91
Width = 65
Height = 13
Caption = 'Thread Count'
end
object CacheEdit: TSpinEdit
Left = 9
Top = 22
Width = 61
Height = 22
MaxValue = 20
MinValue = -1
TabOrder = 0
Value = 0
OnChange = CacheEditChange
end
object PortEdit: TSpinEdit
Left = 8
Top = 64
Width = 60
Height = 22
MaxLength = 4
MaxValue = 9000
MinValue = 1
TabOrder = 1
Value = 1
OnChange = PortEditChange
end
object ThreadCount: TEdit
Left = 8
Top = 107
Width = 62
Height = 21
Color = clBtnFace
ReadOnly = True
TabOrder = 2
Text = '0'
end
end
object Panel2: TPanel
Left = 120
Top = 0
Width = 271
Height = 197
Align = alClient
BevelOuter = bvNone
Caption = 'Panel2'
TabOrder = 1
object ListBox1: TListBox
Left = 0
Top = 21
Width = 271
Height = 176
Align = alClient
ItemHeight = 13
TabOrder = 0
end
object Panel3: TPanel
Left = 0
Top = 0
Width = 271
Height = 21
Align = alTop
Alignment = taLeftJustify
BevelOuter = bvNone
Caption = 'Chars Sent:'
TabOrder = 1
object CharCount: TLabel
Left = 55
Top = 4
Width = 50
Height = 13
Caption = 'CharCount'
end
end
end
object StatusBar1: TStatusBar
Left = 0
Top = 197
Width = 391
Height = 19
Panels = <>
SimplePanel = True
end
object ServerSocket: TServerSocket
Active = False
Port = 1024
ServerType = stThreadBlocking
OnGetThread = ServerSocketGetThread
OnThreadStart = ServerSocketThreadStart
OnThreadEnd = ServerSocketThreadEnd
Left = 315
Top = 1
end
object MainMenu: TMainMenu
Left = 350
Top = 1
object File1: TMenuItem
Caption = '&Server'
object ActiveItem: TMenuItem
Caption = '&Active'
OnClick = ActiveItemClick
end
object N1: TMenuItem
Caption = '-'
end
object Exit1: TMenuItem
Caption = 'E&xit'
OnClick = Exit1Click
end
end
end
end////////////////////////////program server;uses
Forms,
main in 'main.pas' {Form1};{$R *.RES}begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.对你应该有用。