网络编程中如何实现服务器端主动向客户端发消息的功能? ( 积分: 200 )

  • 主题发起人 主题发起人 Bigsun
  • 开始时间 开始时间
B

Bigsun

Unregistered / Unconfirmed
GUEST, unregistred user!
通常服务器完成的任务基本上都是被动的,大部分是响应客户端发出的请求。如何实现服务器端主动向客户端发消息的功能?
 
通常服务器完成的任务基本上都是被动的,大部分是响应客户端发出的请求。如何实现服务器端主动向客户端发消息的功能?
 
要求不需要client做任何动作的。
 
你可以维护一个客户列表,当客户连接服务器的时候将其增加到列表中,离开则删除。
这样就可以方便的给客户端发送消息了。
 
既然没有来自客户端的触发时间,只能是服务器端定时或检测状态来触发了;
 
如果想用TIdTCPServer控件怎么实现呢?
 
很简单,对TIdTCPServer编程时,关键是做一个客户列表,以下是我程序中的部分代码:
procedure TMainForm.SendRebootActionExecute(Sender: TObject);
var CommBlock:TCommBlock;
Client:TSimpleClient;
i:integer;
begin
for i:=0 to AccountListBox.Items.Count-1 do
begin
if AccountListBox.Selected then
begin
Client:=Clients.Items[AccountListBox.ItemIndex];
CommBlock.Command:='@REBOOT';
CommBlock.Msg:='系统重新启动消息';
CommBlock.SendMsgUserName:='系统管理员';
TIdPeerThread(Client.Thread).Connection.WriteBuffer(CommBlock,SizeOf(CommBlock));
end;
end;
end;
 
CommBlock:TCommBlock;
Client:TSimpleClient;

请给出来看看
 
TCommBlock = record // 数据通讯块 (Server+Client)
ComputerPort:integer; //发送端TCP/IP端口
CommDateTime:TDateTime;//通讯时间
Command:string[32]; // 通讯命令
// LOGIN、LOGOUT、ERROR、DOWNLOAD、CLOSE、ONLINE、REBOOT
ComputerIP:string[32]; // 发送端计算机IP
ComputerName:string[32]; // 发送端计算机名称
Msg:string[255]; // 发送消息
SendMsgUserName:string[32]; // 发送消息的用户
ReceiverMsgUserName: string[32]; // 接收消息的用户
end;

TSimpleClient=class(TObject)
CommBlock:TCommBlock;
ConnectedDateTime,
LastActionDateTime:TDateTime;
ListLink:word;
Thread:Pointer;
end;
 
当有CLIENT跟你连接时,在你的SERVER队列中就有一个CLIENT句并,用这个SOCKET句并就可以向CLIENT发送数据了
 
当有CLIENT跟你连接时,在你的SERVER队列中就有一个CLIENT句并,用这个SOCKET句并就可以向CLIENT发送数据了
男生111 能否详细说以下?
我对此感兴趣!
 
通过ServerSocket->Socket->Connections数组,找到你要发送数据的CLIENT,可以得到他的SOCKET,然后就可以发送了
 
不给我分吗?
 
以下代码是使用delphi 6自带的TServerSocket,其实很简单:

procedure TMainForm.LogServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
Var
strIp,strHost:string;
Count,i:Integer;
begin
strIp:=Socket.RemoteAddress;
strHost:=Socket.RemoteHost;
AccountListBox.Items.Add(strIp);

LogMemo.Lines.Add('['+DateTimeToStr(now)+']登陆:'+
' SocketID:'+Inttostr(Socket.SocketHandle)+
', Host:'+strHost+
', IP:'+strIp);
//只要有用户登陆,就将所有登陆用户的IP地址发送给大家,实际使用中可以使用帐户来处理。
//下面代码只是演示,最好另外开线程来处理,否则连接用户>30的话,就很容易出问题。
Count:=LogServerSocket.Socket.ActiveConnections;
for i:=0 to Count-1 do
begin
try
LogServerSocket.Socket.Connections.SendText(AccountListBox.Items.CommaText);
except
end;
end;
end;
 
procedure TfrmMain.BroadcastMessage( WhoFrom, TheMessage : String );
var
Count: Integer;
List : TList;
EMote,
Msg : String;
begin
Msg := Trim(TheMessage);

EMote := Trim(memEMotes.Lines.Values[Msg]);

if WhoFrom <> 'System' then
Msg := WhoFrom + ': ' + Msg;

if EMote <> '' then
Msg := Format(Trim(EMote), [WhoFrom]);

List := tcpServer.Threads.LockList;
try
for Count := 0 to List.Count -1 do
try
TIdPeerThread(List.Items[Count]).Connection.WriteLn(Msg);
except
TIdPeerThread(List.Items[Count]).Stop;
end;
finally
tcpServer.Threads.UnlockList;
end;
end;
 
谢谢参与讨论
 
后退
顶部