多线程阻塞式 Socket ,服务器端如何把在某一个线程中接受到来的信息,再发送给其它线程呢?(200分)

O

Orber

Unregistered / Unconfirmed
GUEST, unregistred user!
多线程阻塞式 Socket ,服务器端如何把在某一个线程中接受到来的信息,再发送给其它线程呢?

 
服务器端用一个列表,每建立一个联接,就记录下该联接线程的线程句柄
然后当要发送信息的时候,就可以 SendMessage 了啊。猜的:)
 
我现在就是用的这种办法。
但是 当只有一个线程的时候,数据可以正确的返回到 客户端,
但是当有大于一个线程的时候, 服务器端的每个线称好像都被堵住似的,连每个线程接收数据都不成功了。

例如 :
当只有客户端1连接到服务器上后,输入信息,可以正确被返回。
当客户端2连接到服务器后,输入信息,客户端1可以看到此信息,但根据跟踪发现 当服务器短通过保存的线程句柄向客户端2发送的时候,没有成功,好像被堵住的感觉。
这时候使用客户端2继续发送的话,好像数据全部都被堵住了,已连接的服务器都看不到。
但当客户端1发送信息时候,刚才被堵住的那些信息,又全部一骨脑全都发送出来了。
很奇怪 :(

附上代码


procedure TCMServerThread.ClientExecute;
var
Data: array[0..1023] of char;
SocketStream: TWinSocketStream;
ADOQuery: TADOQuery;
ADOConnection: TADOConnection;
t:_Recordset;
ReceiveMessage :String;
begin
Synchronize(RegisterForm);
SocketStream := TWinSocketStream.Create(ClientSocket, 600000);
while not Terminated and ClientSocket.Connected do
try
FillChar(Data, SizeOf(Data), 0);
if SocketStream.Read(Data, SizeOf(Data)) = 0 then
begin
ClientSocket.Close;
Synchronize(RemoveForm);
Terminate;
end;
ReceiveMessage := Data;
Send(ReceiveMessage);
except
ClientSocket.Close;
Synchronize(RemoveForm);
Terminate;
end;
end;

procedure TForm1.ServerSocketGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TCMServerThread.Create(False, ClientSocket);
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.RegisterThread(Thread: TServerClientThread);
begin
if Listbox1.Items.IndexOfObject(Thread) = -1 then
ListBox1.Items.AddObject(inttostr(Listbox1.Items.Count), Thread);
end;

procedure TCMServerThread.RegisterForm;
begin
Form1.RegisterThread(self);
end;

procedure TCMServerThread.RemoveForm;
begin
Form1.RemoveThread(self);
end;

procedure TCMServerThread.Send(SMessage:String);
begin
Form1.SendAllMessage(SMessage);
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 TForm1.SendAllMessage(SMessage:String);
var
i: Integer;
begin
for i := 0 to ListBox1.Items.Count - 1 do
begin
with TServerClientThread(ListBox1.Items.Objects) do
begin
Memo1.Lines.Add('index:' + inttostr(i) + ' Message'+SMessage);
ClientSocket.SendText(SMessage);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket.Open;
end;
 
你的 TCMServerThread.ClientExecute; 的循环取数据好像太“霸道”了吧:)
在每个循环里面 Sleep(100); 一下,否则资源占用太高了吧。
或者用 WaitForData
 
我加上 waitfordata 试验了一下,似乎成功了。 但是请问 我写的那个 Send(SMessage:String)方法,是否需要在
在线程中用 Synchronize() 来 调用呢?
但是 由于我那个方法 需要有一个参数的,所以调用起来会出错误.

请指教。
 
你的代码好像有很多漏洞嘛 该free的没有释放
 
多线程数据共享,需要临界量,数据更新完后,用POSTTHREADMESSAGE通知目标线程读
 
顶部