请问我建立了一个TServerClientThread 线程,但是怎么在线程外面控制该线程呢?(40分)

  • 主题发起人 主题发起人 Orber
  • 开始时间 开始时间
O

Orber

Unregistered / Unconfirmed
GUEST, unregistred user!
请问我建立了一个TServerClientThread 线程,但是怎么在线程外面控制该线程呢?
比如控制该线程的ClientSocket 对象。

 
它里面不是有个ClientExecute方法给你继承,然后你在
写两个函数,同步增加到MainForm中的TList/TStrings的列表中,然后使用时,安全转换使用


procedure Thread.ClientExecute;
begin
//Synchronize(RegisterYourMainForm); //用同步方法
try

finally
//Synchronize(RemoveYourMainForm); //用同步方法
end;
end;

procedure RegisterYourMainForm;
begin
MainForm.RegisterThread(Self);
end;

procedure RemoveYourMainForm;
begin
MainForm.RemoveThread(Self);
end;

procedure MainForm.RegisterThread(Thread: TServerClientThread);
begin
if Listbox1.Items.IndexOfObject(Thread) <> -1 then
ListBox1.Items.AddObject('Some thread', Thread);
end;

procedure MainForm.RemoveThread(Thread: TServerClientThread );
var
INdex: Integer;
begin
Index := ListBox1.Items.IndexOfObject(Thread);
if Index <> -1 then
Listbox1.Items.Delete(Index);
end;
 
请问我在 ListBox1中添加了一个线程对象后,怎么适用他呢?
例如我要使用此线程的 ClientSocket.SendText('xxx');
是否是这样使用?
Form1.ListBox1.Items.Objects[1].ClientSocket.SendText('xx');
但是 到了 Objects[1]. 这部分 根本找不到 ClientSocket 这个对象了。

请高手指教。
 
with TServerClientThread(ListBox1.Items.Objects[0]) do
begin
ClientSocket.SendBuf(;asdlfja;sldkfjasdf;);
end;
 
谢谢,但是我加入到我的程序中后,一执行这段语句,服务端的程序就没有响应了,好像死在哪里,又好像死循环了,过了好一段时间,发送成功了,但是客户端显示已经被中断了连接。。。
请问该如何处理? 谢谢
以下是我的 Threand 执行代码
procedure TFileServerThread.ClientExecute;
var
Data: array[0..1023] of char;
FileName: String;
begin
Form1.ListBox1.Items.AddObject('somethread',self);
while not Terminated and ClientSocket.Connected do
try
SocketStream := TWinSocketStream.Create(ClientSocket, 60000);
try
FillChar(Data, SizeOf(Data), 0);
if SocketStream.Read(Data, SizeOf(Data)) = 0 then
begin
ClientSocket.Close;
Terminate;
end;
FileName := Data;
ClientSocket.SendText(FileName);
end;
except
SocketStream.Free;
end;
except
HandleException;
end;
end;
 
procedure TFileServerThread.ClientExecute;
var
Data: array[0..1023] of char;
FileName: String;
begin
// Form1.ListBox1.Items.AddObject('somethread',self);
//用我上面写的方法,不要直接用Form1这个对象,不然也就没必要写多线程了。
//线程访问VCL组件,要用同步方法
//一般用的多的是Synchronize这个方法,当然还有其它,不过这个简单。
//记得最后Remove Self

while not Terminated and ClientSocket.Connected do
try
SocketStream := TWinSocketStream.Create(ClientSocket, 60000);
//将上面一句放到循环外面,不然一个循环Create Free,有点浪费
try
FillChar(Data, SizeOf(Data), 0);
if SocketStream.Read(Data, SizeOf(Data)) = 0 then
begin
ClientSocket.Close;
Terminate;
end;
FileName := Data;
ClientSocket.SendText(FileName);
end;
except
SocketStream.Free;
end;
except
HandleException;
end;
end;
 
下面代码,是我依照你所说的修改过的,但是放到程序中,编译会出现 Self 未被定义的错误。
请问改如何解决? 谢谢
Form1:TForm1

procedure RegisterForm;
begin
TForm1.RegisterThread(Self);
end;

procedure RemoveForm;
begin
TForm1.RemoveThread(Self);
end;

procedure TForm1.RegisterThread(Thread: TServerClientThread);
begin
if Listbox1.Items.IndexOfObject(Thread) <> -1 then
ListBox1.Items.AddObject('Some thread', Thread);
end;

procedure TForm1.RemoveThread(Thread: TServerClientThread );
var
INdex: Integer;
begin
Index := ListBox1.Items.IndexOfObject(Thread);
if Index <> -1 then
Listbox1.Items.Delete(Index);
end;

 
谢谢你,经过修改,程序终于可以了,感谢您的一直帮助。
procedure TFileServerThread.RegisterForm;
begin
Form1.RegisterThread(Self);
end;

procedure TFileServerThread.RemoveForm;
begin
Form1.RemoveThread(Self);
end;

procedure TForm1.RegisterThread(Thread: TServerClientThread);
begin
if Listbox1.Items.IndexOfObject(Thread) = -1 then
ListBox1.Items.AddObject('Some thread', Thread);
memo1.Lines.Add(inttostr(Listbox1.Items.IndexOfObject(Thread)));
end;

procedure TForm1.RemoveThread(Thread: TServerClientThread );
var
INdex: Integer;
begin
Index := ListBox1.Items.IndexOfObject(Thread);
if Index <> -1 then
Listbox1.Items.Delete(Index);
end;
 
想请教一个问题:
  是这样的,
  如何关闭所有的线程?
  尽量给些代码。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;

type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
ClientSocket1: TClientSocket;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Edit1: TEdit;
Button5: TButton;
procedure ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure ServerSocket1ThreadEnd(Sender: TObject;
Thread: TServerClientThread);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
TFileServerThread=Class(TServerClientThread)
public
procedure ClientExecute;override;
end;
var
Form1: TForm1;
a:TFileServerThread;
implementation

{$R *.dfm}

procedure TForm1.ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
//
a:=TFileServerThread.Create(False,ClientSocket);
SocketThread:=a;

Memo1.Lines.Add(IntToStr(ClientSocket.SocketHandle));
//ClientSocket.SendText('Welcome to Server'+#13#10);
end;

{ 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);
FreeOnTerminate:=True;
try
FillChar(Data,Sizeof(Data),0);
if SocketStream.Read(Data,SizeOf(Data))=0 then
begin
ClientSocket.SendText('gsw798'+#13#10);
Sleep(1);
ClientSocket.Close;
Terminate;
end;
RecText:=Data;
if Length(RecText)>2 then
Delete(RecText,Pos(#13#10,RecText),2);
if ClientSocket.Connected then
begin
ClientSocket.SendText(RecText);
end;
finally
SocketStream.Free;
end;
except
synchronize(HandleException);
end;
ClientSocket.Close;
Terminate;

end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(Socket.ReceiveText);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
str:string;
i:integer;
begin
TServerClientThread(a).Terminate;
TServerClientThread(a).Free;
sleep(5000);
if ServerSocket1.Socket.ActiveThreads=0 then
begin
showmessage('yes');
ServerSocket1.Close;
end
else
showmessage('no');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ClientSocket1.open;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
ClientSocket1.Close;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(Edit1.Text);
end;

procedure TForm1.ServerSocket1ThreadEnd(Sender: TObject;
Thread: TServerClientThread);
begin

end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(IntToStr(Socket.SocketHandle))
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
// Memo1.Lines.Add(IntToStr(Socket.SocketHandle));
end;

end.
 
  你们说的我明白一些,就是在线程开始和结束时记录他们,
  但是,如何结束等待中(也就是线程在等待联接或数据时)的线程?
  急盼你的回答!!!全天候等待!!
  QQ:27191895,gsw798@163.net
 
后退
顶部