Delphi TIdTCPClient的使用问题

2023-11-08

开发环境Delphi10.3.3

使用TIdTCPClient写了一个客户端小例子,使用网络调试助手作为服务端(设置接收到客户端信息会自动返回数据)。

通讯模式:短连接。客户端连接--发送---等待数据---接收---断开。此例子中客户端不知道返回信息长度是多少。

问题:由于不确定服务端返回数据多少,所以使用Socket.ReadBytes(dat,-1,False); -1:表示一直读取直到超时。本以为像ClientSocket那样有多少数据就能读到多少,结果试验了不同长度的数据,读取到的长度也不一样。1000多个字节没问题,超过2920就会出现读取不够的情况(经常在2920出问题,但也不全是)。读取结束后disconnect,再次connect就会抛出Already connected异常。

如果Socket.ReadBytes(dat,-1,False);  第二个参数设置为正数,表示要读取的字节数,如果实际返回的小于参数则会一直等待到readtimeout,然后抛出超时异常。如果大于参则读取成功。但这两种情况都是导致再次connect抛出Already connected异常。

解决Already connected异常的办法是idtcpclnt1.Socket.InputBuffer.Clear;

解决读取数据不够的办法是循环调用Socket.ReadBytes(dat,-1,False); 

改进后如下:

procedure TReadThread.Execute;
var
  dat:TIdBytes;
  msg:AnsiString;
  count:Integer;
  tcpclient:TIdTCPClient;
begin
  FreeOnTerminate:=true;
  try
    tcpclient:=TIdTCPClient.Create();
    with tcpclient do
    begin
      Host := Form1.edtIP.Text;
      Port := StrToInt(Form1.edtPort.Text);
      Connect;
      Form1.mmo1.Lines.Add('connected') ;
      Socket.Write('阿斯蒂芬',IndyTextEncoding_OSDefault);

      Form1.mmo1.Lines.Add('等待接收') ;
      Socket.ReadTimeout:=1000*6;//读取超时时间

      if Socket.CheckForDataOnSource(1000*60) then//等待数据60秒,有数据返回true
      begin
        repeat
          SetLength(dat, 0); 
          Socket.ReadBytes(dat,-1,False);
          count:=count+Length(dat);
          msg:=BytesToString(dat,IndyTextEncoding_OSDefault);

          Form1.mmo1.Lines.Add('数据长度:'+IntToStr(Length(dat))) ;
        until (Socket.CheckForDataOnSource(500)=False);

        Form1.mmo1.Lines.Add('总长度:'+IntToStr(count)) ;
      end
      else
      begin
        if Connected then
          Form1.mmo1.Lines.Add('等待超时')
        else
          Form1.mmo1.Lines.Add('已断开连接') ;
      end;
      //关闭
      if connected then
      begin
        if Socket.InputBufferIsEmpty then
          Form1.mmo1.Lines.Add('true')
        else
          Form1.mmo1.Lines.Add('false');
        Socket.InputBuffer.Clear;
        DisConnect;
      end;
    end;
  except
  on E : Exception do
    begin
      Form1.mmo1.Lines.Add('异常:'+E.Message+'['+e.ClassName+']');
    end;
  end;
end;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi TIdTCPClient的使用问题 的相关文章

随机推荐

  • springboot在集成多数据源+mybatis-plus无法进行分页的BUG

    springboot在集成多数据源 mysql psql 解决多数据源mybatis plus无法进行分页的BUG 1 springboot在集成多数据源 1 1引入依赖 1 2配置yml文件 1 3创建config包 这个只要让Sprin
  • py 语法操作小计

    list只能加 a b set 只能减 a b parser 传参数 test py import argparse parser argparse ArgumentParser description Training GNN on Pa
  • Linux系统编程-终端、进程组、会话

    一 终端的概念 在UNIX系统中 用户通过终端登录系统后得到一个Shell进程 这个终端成为Shell进程的控制终端 Controlling Terminal 进程中 控制终端是保存在PCB中的信息 而fork会复制PCB中的信息 因此由S
  • 百度地图根据经纬度获取实际地理位置Api接口

    1 接口URL http api map baidu com reverse geocoding v3 ak 密钥 output json coordtype bd09ll location 33 35194364323275 117 39
  • 【附源码】单点登录的两种实现方式

    概念 单点登录 Single Sign On SSO 是一种身份验证服务 允许用户使用单个标识来登录多个应用程序或系统 如下图所示 用户只需要用户名 密码登陆一次就可以访问系统A 系统B和系统C 在传统的登录方式中 用户必须为每个应用程序或
  • 目录扫描,请求重发,漏洞扫描等工具的使用

    本专栏是笔者的网络安全学习笔记 一面分享 同时作为笔记 工欲善其事必先利其器 本篇讲解一些常用工具的使用 前文链接 WAMP DVWA sqli labs 搭建 burpsuite工具抓包及Intruder暴力破解的使用 用到的工具 bur
  • 7天学完Spring:AOP实战,SpringMVC统一处理

    目录 前言 一丶用户登录权限效验 lt 1 gt 最初用户登录验证 lt 2 gt Spring AOP 用户统一登录验证的问题 lt 3 gt 拦截器 拦截功能演示 lt 4 gt 拦截器原理 lt 5 gt 统一访问前缀添加 二丶统一异
  • 操作系统期末习题考试习题解答题目三

    操作系统期末习题考试习题解答题目三 目录 操作系统期末习题考试习题解答题目三 第八章 第九章 第八章 1 什么是文件 文件系统 文件系统有哪些功能 P198 答 在计算机系统中 文件被解释为一组赋名的相关字符流的集合 或者是相关纪录的集合
  • 理解git存储原理

    git是一个文件寻址系统 什么是文件寻址 其实我也不是很理解 哈哈哈 Git 的底层存储从本质上讲是基于本地文件系统实现的 Key Value 数据库 这里的 Value 是 git 里的三种不同的对象的内容 而 Key 则是对象内容的 h
  • VML Mathematical Functions

    http www physics ntua gr konstant HetCluster intel12 1 mkl mkl manual GUID 7B3B6537 71E2 4BF5 A041 0365E72B211B htm TBL9
  • opencv c++ 贴图补齐实战

    目录 创建黑图 int8类型贴图补齐 测试时间 fx缩放 贴图 float32类型贴图
  • ChatGPT作者John Shulman:我们成功的秘密武器

    推荐 深度学习与NLP 来源 转载自OneFlow 杨婷 徐佳渝翻译 除了OpenAI 外界可能很少有人知道ChatGPT模型成功的真正原因 实际上 OpenAI也会对ChatGPT拥有的巨大影响力感到不可思议 这种困惑和惊喜就像工程师们解
  • CV-第三方库:OpenMMLab---->MMClassification

    MMClassification 是一款基于 PyTorch 的开源图像分类工具箱 是 OpenMMLab 项目的成员之一 主分支代码目前支持 PyTorch 1 5 以上的版本 主要特性 支持多样的主干网络与预训练模型 支持配置多种训练技
  • Android 获取网络连接状态新方法

    一 问题背景 Android12上 有的app模块判断当前网络的类型和连接状态时 还是使用的旧的API 导致返回的结果不准确 影响代码逻辑判断 本篇文章就这一问题 整理一下判断网络类型和连接状态的新方法 二 原因分析 在Android 10
  • Flutter学习-TextField

    目录 focusNode 获取焦点 decoration InputDecoration边框装饰 keyboardType TextInputType 输入的类型 textCapitalization TextCapitalization
  • 使用Angular编写用户管理系统前台界面

    目录 工作准备 项目框架 功能描述 工作准备 安装node js node js中包含了npm node v查看node版本 npm v查看npm版本 全局安装angular CLI npm install g angular cli ng
  • win11系统激活修复

    打开终端 输入以下代码 irm https massgrave dev get iex 在弹出的窗口中 选择1即可
  • jquery 中 $(".XXX") 和 $("#XXX")的区别

    XXX 为获取类名为XXX的类 XXX 为获取id为XXX的标签
  • cesium 申请秘钥(Cesium.Ion.defaultAccessToken/access_token)

    https cesium com ion signin tokens 然后注册 登录 复制使用 Cesium Ion defaultAccessToken 你的 token 案例
  • Delphi TIdTCPClient的使用问题

    开发环境Delphi10 3 3 使用TIdTCPClient写了一个客户端小例子 使用网络调试助手作为服务端 设置接收到客户端信息会自动返回数据 通讯模式 短连接 客户端连接 发送 等待数据 接收 断开 此例子中客户端不知道返回信息长度是