DataSnap如何监控Tcp/IP客户端的连接情况
一个实例,如果客户端是TCP/IP是短连接的情况就没有必要了。
一、GlobVar.pas单元,定义应用系统全局数据类型及变量:
unit GlobVar; interface uses System.SysUtils, System.Classes,IdTCPConnection,System.Generics.Collections,
Datasnap.DSTCPServerTransport,IdWinsock2,Data.DBXCommon,Datasnap.DBClient,
Datasnap.DSServer, Datasnap.DSCommonServer; type
pClientConns = ^TClientConns; // 客户连接 TClientConns = record
ClientId: integer;
Ip: string;
Port: string;
LoginTime: TDateTime;
end; const
gb_MaxConnNum = ;//每个进程最大连接数设置为1000 var
gb_ClientConnects: TDictionary<TIdTCPConnection, pClientConns>; // 客户端连接字典
gb_ConnnectCount:Integer=; //....
二、ServerContainer1.pas单元:
uses GlobVar;
//...
procedure TServerContainer1.DSTCPServerTransport1Connect(Event: TDSTCPConnectEventObject);
var
p: pClientConns;
begin
try
if gb_ConnnectCount >= gb_MaxConnNum then
begin
LogInfo('已超过系统授权的客户连接数');
TIdTCPConnection(Event.Connection).Disconnect;
Exit;
end;
InterlockedIncrement(gb_ConnnectCount);
New(p);
if Assigned(p) then
begin
p^.ClientId := Event.Channel.ChannelInfo.Id;
p^.Ip := Event.Channel.ChannelInfo.ClientInfo.IpAddress;
p^.Port := Event.Channel.ChannelInfo.ClientInfo.ClientPort;
p^.LoginTime := Now;
gb_ClientConnects.Add(TIdTCPConnection(Event.Connection), p);
PostMessage(Application.SrvMainForm.Handle, WM_ADDUSER, wParam(p),lParam(TIdTCPConnection(Event.Connection)));
end;
except
Exit;
end;
end; procedure TServerContainer1.DSTCPServerTransport1Disconnect(Event: TDSTCPDisconnectEventObject);
var
p: pClientConns;
begin
try
if gb_ConnnectCount >= then
InterlockedDecrement(GlobalVar.gb_ConnnectCount);//GlobalVar.pas单元中定义了系统全局变量
p := gb_ClientConnects.Items[TIdTCPConnection(Event.Connection)];
if Assigned(p) then
begin
SendMessage(Application.SrvMainForm.Handle, WM_DELUSER, wParam(p), );
gb_ClientConnects.Remove(TIdTCPConnection(Event.Connection));
end;
except
Exit;
end;
end;
三、SrvMainForm.pas
procedure TSrvMainForm.AddUser(var msg: TMessage);
var
p: pClientConns;
begin
try
lbl_MaxCount.Caption := IntToStr(gb_ConnnectCount);
p := pClientConns(msg.WParam);
if Assigned(p) then
begin
ClientDataSet1.Append;
ClientDataSet1.FieldByName('Id').AsInteger := p^.ClientId;
ClientDataSet1.FieldByName('Ip').AsString := p^.Ip;
ClientDataSet1.FieldByName('Port').AsString := p^.Port;
ClientDataSet1.FieldByName('LoginTime').AsDateTime := p^.LoginTime;
ClientDataSet1.FieldByName('Conn').AsInteger := msg.LParam;
ClientDataSet1.Post;
end;
except
on E: Exception do
begin
LogInfo('TSrvMainForm.AddUser---' + E.Message);
exit;
end;
end;
end; procedure TSrvMainForm.DelUser(var msg: TMessage);
var
p: pClientConns;
begin
try
lbl_MaxCount.Caption := IntToStr(gb_ConnnectCount);
p := pClientConns(msg.WParam);
if Assigned(p) then
begin
if ClientDataSet1.FindKey([p^.ClientId]) then //Id字段请设置索引
ClientDataSet1.Delete;
Dispose(p);
end;
except
on E: Exception do
begin
LogInfo('TSrvMainForm.DelUser---' + E.Message);
Exit;
end;
end;
end;
版权声明:本文为博主原创文章,未经博主允许不得转载。
DataSnap如何监控Tcp/IP客户端的连接情况的更多相关文章
- [转]linux下iftop工具的安装与使用详解(图文)——实时的网络流量,监控TCP/IP连接(单机)
原文链接:http://www.jbxue.com/LINUXjishu/10735.html 在linux中监控系统资源.进程.内存占用等信息,可以使用top命令.查看网络状态可以使用netstat ...
- datasnap 如何监控客户端的连接情况
如果客户端是TCP/IP是短连接的情况就没有必要了. type pClientConns = ^TClientConns; // 客户连接 TClientConns = record clientid ...
- TCP/IP详解--连接状态变迁图CLOSE_WAIT
终止一个连接要经过4次握手.这由TCP的半关闭(half-close)造成的.既然一个TCP连接是全双工(即数据在两个方向上能同时传递,可理解为两个方向相反的独立通道),因此每个方向必须单独地进行关闭 ...
- 基于TCP/IP的长连接和短连接
1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...
- TCP/IP系列——长连接与短连接的区别
1 什么是长连接和短连接 三次握手和四次挥手 TCP区别于UDP最重要的特点是TCP必须建立在可靠的连接之上,连接的建立和释放就是握手和挥手的过程. 三次握手为连接的建立过程,握手失败 ...
- 2015/12/14 Python网络编程,TCP/IP客户端和服务器初探
一直不是很清楚服务器的定义,对于什么是服务器/客户端架构也只有一个模糊的感觉.最近开始学习,才明白一些什么服务器和客户端的关系. 所谓的服务器,就是提供服务的东西,它是一个硬件或者软件,可以向一个或者 ...
- tcp/ip客户端与服务器
单击“发送数据”把数据发送到指定IP地址的指定端口号 using System; using System.Collections.Generic; using System.ComponentMod ...
- SQL Server 连接问题-TCP/IP
原文:SQL Server 连接问题-TCP/IP 出自:http://blogs.msdn.com/b/apgcdsd/archive/2012/02/24/ms-sql-server-tcp-ip ...
- TCP/IP, WebSocket 和 MQTT
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的协议.在这三者之间, TCP是HTTP和MQTT底层的协议.大家对HTTP很熟悉,这里简要介绍下MQTT.M ...
随机推荐
- Android消息推送完美方案
转自:http://bbs.hiapk.com/thread-4652657-1-1.html 推送功能在手机应用开发中越来越重要,已经成为手机开发的必须.在Android应用开发中,由于众所周知的原 ...
- 【Shell脚本学习1】Shell简介:什么是Shell,Shell命令的两种执行方式
Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释 ...
- java产生不重复的随机数
/** *产生9位不同的随机数 */ private String getRandomString(){ StringBuffer sb = new StringBuffer(); for(int i ...
- React Native学习-measure测量view的宽高值
measure()测量是根据view标签中的ref属性,使用方法如下: measureWatermarkerImage(){ this.refs.watermarkerImage.measure((a ...
- HDU 2571 命运 (DP)
命运 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Pr ...
- java多线程之Future和FutureTask
Executor框架使用Runnable 作为其基本的任务表示形式.Runnable是一种有局限性的抽象,然后可以写入日志,或者共享的数据结构,但是他不能返回一个值. 许多任务实际上都是存在延迟计算的 ...
- 【CSS3】---结构性伪类选择器-first-child+last-child
结构性伪类选择器—first-child “:first-child”选择器表示的是选择父元素的第一个子元素的元素E.简单点理解就是选择元素中的第一个子元素,记住是子元素,而不是后代元素. 示例演示 ...
- android 使用NinePatch图作Background,导致布局混乱
在Layout中使用NinePatch图片作为其布局的背景图片时,可能会导致Layout中的布局发生混乱,此时将此Layout设置一个属性:android:padding="0dp" ...
- Android ListView动态改变Item高度
在adapter的getView方法中进行设置,代码如下 @Override public View getView(int position, View convertView, ViewGroup ...
- C# 获取文件名及扩展名
C# 获取文件名及扩展名 string aFirstName = aFile.Substring(aFile.LastIndexOf("\\") + 1, (aFile.LastI ...