热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

TServerSocket:如何在发送消息之前检查ListView上的特定客户端是否仍处于连接状态?

如何解决《TServerSocket:如何在发送消息之前检查ListView上的特定客户端是否仍处于连接状态?》经验,为你挑选了1个好方法。

我有一个Timer,想要向每个客户端发送一条消息ListView,例如确定ping时间。然后我有以下代码:

procedure TMainForm.Timer1Timer(Sender: TObject);
var
  i: Integer;
begin
  try
    for i := 0 to ListView1.Items.count - 1 do
    begin
      ListView1.Items.Item[i].SubItems.Objects[2] := TObject(GetTickCount);
      ServerSocket1.Socket.Connections[i].SendText('ping' + #13#10);
    end;
  except
    exit;
  end;
end;

在发送之前,可以更适当地检查客户端是否已真正连接或类似的连接。怎么做?提前致谢。



1> Remy Lebeau..:

无需检查连接。如果客户端实际上已断开连接,则在触发处理程序Connections[]时,该客户端将不再位于服务器列表中OnTimer。您应该为OnClientDisconnect分配了处理程序,以TServerSocket从中删除客户端TListView

如果由于某种原因,客户端仍在Connections[]列表中(即,由于基础连接已丢失但TServerSocket尚未检测到),则套接字将仅缓存所有传出数据,直到其出站缓冲区填满为止,然后将开始WSAWOULDBLOCK为每个发送返回错误。最终,操作系统将使死连接超时并TServerSocketConnections[]列表中将其删除,从而触发OnClientDisconnect事件。

至少,在显示的代码中,应该将send循环更新为Close()实际上无法发送的任何套接字,从而触发OnClientDisconnect事件以从中删除该客户端TListView,例如:

procedure TMainForm.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Data := Socket;
  ...
end;

procedure TMainForm.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Item: TListItem;
begin
  Item := ListView1.FindData(0, Socket, True, False);
  if Item <> nil then
    Item.Delete;
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
const
  s: AnsiString = 'ping' + #13#10;
var
  Item: TListItem;
  Socket: TCustomWinSocket;
  p: PAnsiChar;
  i, len, sent: Integer;
begin
  for i := 0 to ListView1.Items.Count - 1 do
  begin
    Item := ListView1.Items[i];
    Item.SubItems.Objects[2] := TObject(GetTickCount);
    Socket := TCustomWinSocket(Item.Data);
    try
      // SendText() does not handle partial sends, or Unicode strings...
      //Socket.SendText('ping' + #13#10);
      p := PAnsiChar(s);
      len := Length(s);
      repeat
        sent := Socket.SendBuf(p^, len);
        if sent = -1 then
        being
          if WSAGetLastError() <> WSAEWOULDBLOCK then
            Break;
          // TODO: stop trying after several attempts fail...
          Continue;
        end;
        Inc(p, sent);
        Dec(len, sent);
      until len = 0;
      if len = 0 then
        Continue;
    except
    end;
    Socket.Close;
  end;
end;


推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 达人评测 酷睿i5 12450h和锐龙r7 5800h选哪个好 i512450h和r75800h对比
    本文介绍了达人评测酷睿i5 12450h和锐龙r7 5800h选哪个好的相关知识,包括两者的基本配置和重要考虑点。希望对你在选择时提供一定的参考价值。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了关于smarty自定义缓存名的解决思路,通过放弃生成缓存,直接生成html的静态页面来提高速度。同时提供了一个参考链接供参考。 ... [详细]
author-avatar
吴慈瑋宗杰
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有