Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么当客户端连接到Indy中的服务器时,IOHandler.ReadStream会阻止线程?

为什么当客户端连接到Indy中的服务器时,IOHandler.ReadStream会阻止线程?
EN

Stack Overflow用户
提问于 2010-07-25 10:01:33
回答 1查看 5.6K关注 0票数 3

今天,我在使用Indy10(Delphi2010附带的)时遇到了一个奇怪的行为。以下是问题所在:

假设我们的客户端中有一个IdTcpClient,服务器应用程序中有一个IdTcpServer,IdTcpServer的OnExecute事件处理程序中有以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  AStream: TStringStream;
  S: string;
begin
  AStream := TStringStream.Create;
  try
    AContext.Connection.IOHandler.ReadStream(AStream);
    S := AStream.DataString;
  finally
    AStream.Free;
  end;
end;

现在,当客户机尝试使用TIdTcpClient.Connect连接到服务器时,在服务器上调用TIdTcpServer.OnExecute,并且当执行到达AContext.Connection.IOHandler.ReadStream(AStream)行时,在OnExecute事件处理程序中运行的线程将被阻塞!

当我跟踪代码时,当在ReadStream内部调用ReadLongInt来获取字节计数时,问题就出现了。ReadLongInt调用ReadBytes。在ReadBytes内部,FInputBuffer.Size为零。在那里,在一个循环中调用ReadFromSource,最终执行到达TIdSocketListWindows.FDSelect,它从WinSock2调用"select“函数,执行在这里停止,不会从客户端连接接收任何东西。我也尝试过为AByteCount和AReadUntilDisconnect参数赋值,但这并没有改变行为。

如果我用ReadLn替换ReadStream,那么连接到服务器不会阻止代码执行,并且从客户端发送的数据将由服务器读取。

代码有什么问题吗?或者这是一个bug?

问候

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-07-27 06:41:37

问题出在您的代码中,而不是ReadStream()中。它正在按照设计的方式运行。

它接受3个参数作为输入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
procedure ReadStream(AStream: TStream; AByteCount: TIdStreamSize = -1; AReadUntilDisconnect: Boolean = False); virtual;

您只提供了第一个参数的值,因此其他两个参数使用默认值。

AByteCount参数设置为-1并且AReadUntilDisconnect参数设置为False时,ReadStream()被设计为假定接收的前4个字节(如果IOHandler.LargeStream属性设置为True,则为8个字节)是要发送的数据的长度,随后是实际数据的长度。这就是ReadStream()调用ReadLongInt()的原因。这不仅告诉ReadStream()何时停止读取,而且还允许ReadStream()在接收数据之前预先调整目标TStream的大小,以便更好地进行内存管理。

如果客户端实际上没有在其数据之前发送4字节(或8字节)的长度值,那么ReadStream()仍然会将实际数据的开始字节解释为长度。这通常(但并非总是,取决于数据)会导致ReadLongInt() (或ReadInt64())返回一个大整数值,这将导致ReadStream()预计将有大量数据实际上永远不会到达,从而无限期地阻止读取(或者直到发生超时,如果IOHandler.ReadTimeout属性设置为非无限超时)。

为了有效地使用ReadStream(),它需要知道何时停止读取,要么提前被告知需要多少数据(例如:AByteCount >= 0),要么要求发送者在发送数据后断开连接(例如:AReadUtilDisconnect = True)。当长度直接在流中编码时,AByteCount = -1AReadUtilDisconnect = False的组合是一个特例。这主要用于(但不限于)发送方在其AWriteByteCount参数设置为True (默认情况下为False )的情况下调用IOHandler.Write(TStream)

在处理非文本数据时,尽可能在实际数据之前发送数据长度总是一个好主意。它优化了读取操作。

ReadStream()的不同参数组合符合以下逻辑:

disconnected.

  • AByteCount

  • AByteCount = -1,AReadUtilDisconnect = False:读取4/8个字节,解释为一个长度,然后继续读取,直到长度为disconnected.

  • AByteCount< -1,AReadUtilDisconnect = False:假设AReadUntilDisconnect为True,并继续读取,直到disconnected.

  • AByteCount > -1,= False:预先调整目标
  1. 大小,并继续读取,直到字节数为received.
  2. AByteCount <= -1,AReadUtilDisconnect = True:继续读取,直到AReadUtilDisconnect > -1,AReadUtilDisconnect = True:预调目标TStream的大小并一直读到disconnected.

根据客户机最初实际发送到服务器的数据类型,ReadStream()可能不是读取该数据的最佳选择。IOHandler提供了许多不同类型的读取方法。例如,如果客户端发送分隔文本(尤其是使用IOHandler.WriteLn()发送的文本),则ReadLn()是更好的选择。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3328752

复制
相关文章
Anbox:在 Linux 上运行 Android 应用程序的简单方式
Anbox 是 “Android in a box” 的缩写。Anbox 是一个基于容器的方法,可以在普通的 GNU/Linux 系统上启动完整的 Android 系统。
用户8639654
2021/09/23
5.2K0
7个有用的Pandas显示选项
andas是一个在数据科学中常用的功能强大的Python库。它可以从各种来源加载和操作数据集。当使用Pandas时,默认选项就已经适合大多数人了。但是在某些情况下,我们可能希望更改所显示内容的格式。所以就需要使用Pandas的一些定制功能来帮助我们自定义内容的显示方式。
deephub
2023/02/01
1.3K0
使枚举类型的选项在VS的属性窗里显示为中文
我们自己做的组件,一般希望它的属性在设计时能够在属性窗里显示为中文,可以在属性上添加System.ComponentModel.DisplayNameAttribute标注达到这个目的。但是,枚举的选项如何以中文的形式显示在属性窗里呢?
明年我18
2019/09/18
1.2K0
使枚举类型的选项在VS的属性窗里显示为中文
Spring Boot 如何以 Web 应用的方式启动
https://www.cwiki.us/display/SpringBootZH/questions/57938770
HoneyMoose
2020/04/04
4510
Spring Boot 如何以 Web 应用的方式启动
带有-i选项的sed命令在Linux上执行成功,但在MacOS上失败
就地编辑文件(如果提供了后缀,则进行备份),可见参数后缀 SUFFIX 是可选的,即带或者不带这个参数都可以执行。
程序熵
2023/09/25
3770
带有-i选项的sed命令在Linux上执行成功,但在MacOS上失败
EXCEL单元格的引用方式
EXCEL单元格的引用包括相对引用、绝对引用和混合引用三种。 相对引用   公式中的相对单元格引用(例如 A1)是基于包含公式和单元格引用的单元格的相对位置。如果公式所在单元格的位置改变,引用也随之改变。如果多行或多列地复制公式,引用会自动调整。默认情况下,新公式使用相对引用。例如,如果将单元格 B2 中的相对引用复制到单元格 B3,将自动从 =A1 调整到 =A2。 绝对引用   单元格中的绝对单元格引用(例如 $A$1)总是在指定位置引用单元格。如果公式所在单元格的位置改变,绝对引用保持
用户1075292
2018/01/23
1.4K0
将jpeg图片显示在framebuffer上
点击(此处)折叠或打开 /************************************************** * example5.c * Author: T-bagwell * * Compile:gcc -Wall example5.c -o example5 *************************************************/ #include <stdio.h> #inclu
用户3765803
2019/03/05
1.2K0
跳跃表---用简单的方式实现有序集合
遍历整个链表,时间复杂度为O(n),例如我们向查找7,即node4,需要4次查找
用户3946442
2022/04/11
4230
跳跃表---用简单的方式实现有序集合
[ASP.NET Core 3框架揭秘] Options[2]: 配置选项的正确使用方式[下篇]
前面演示的几个实例具有一个共同的特征,即都采用配置系统来提供绑定Options对象的原始数据,实际上,Options框架具有一个完全独立的模型,可以称为Options模型。这个独立的Options模型本身并不依赖于配置系统,让配置系统来提供配置数据仅仅是通过Options模型的一个扩展点实现的。在很多情况下,可能并不需要将应用的配置选项定义在配置文件中,在应用启动时直接初始化可能是一种更方便快捷的方式。
蒋金楠
2020/02/12
9320
显示器 设置选项 解析
明亮度 Gama:显示器的输出图像对输入信号的失真程度。 DCR:Dynamic Contrast Ratio,动态对比率。自动判断画面整体亮度,对画面各部分进行亮度调整,使细节更清晰,层次更分明。 颜色设置 色温 暖色 正常 冷色 sRGB:RGB(色彩空间)的一种标准。 DCB模式 OSD设置 其他 DDC/CI:Display Data Channel Command Interface,基于DDC/CI协议,用户可以通过鼠标和人性化的软件界面来完成显示器的各项设置和色彩调节,
JNingWei
2018/09/28
1.6K0
直接iframe方式在网页上显示天气插件
天气预报调用网址(可定制):http://www.tianqi.com/plugin/
科控物联
2023/09/22
1.4K0
直接iframe方式在网页上显示天气插件
PageRank算法在spark上的简单实现
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzy0623/article/details/51383232
用户1148526
2019/05/25
1.5K0
Excel表格的35招必学秘技[配图]
一、让数据按需排序   如果你要将员工按其所在的部门进行排序,这些部门名称既的有关信息不是按拼音顺序,也不是按笔画顺序,怎么办?可采用自定义序列来排序。   1.执行“格式→选项”命令,打开“选项”
ytkah
2018/03/06
7.6K0
Excel表格的35招必学秘技[配图]
显示方式
08.05自我总结 一.显示方式 1.display 常用的三种方式 #第一种block 1.支持设置宽高 2.自带换行 一般情况所有有宽高、参与位置布局的都是block #第二种inline 1.不支持设置宽高,宽高只能有文本撑开 2.不带换行,一行显示不下会自动换行(保留数据的整体性) 一般情况存放文本的 #第三种inline-block 1.支持设置宽高 2.不带换行,一行显示不下会自动换行(以标签整体换行,标签左右有间距) 一般情况不去主动设置该显示方式,系统的两个img、input都设置为了单
小小咸鱼YwY
2019/09/11
6530
支持公式的3款Excel替代品
随着大数据、企业数字化转型等不可逆趋势的推动下,似乎一切变得皆可量化和数据化,企业在解决问题时,也更为倾向于以数据表格来作为判断决策是否正确的重要标志,这时具有数据思维和数据分析处理技能,成了当前及未来人才发展不可忽视的能力之一。今天给大家带来3款Excel替代品的对比,由大家来评判一下。
用户10264843
2023/02/09
3.5K0
[ASP.NET Core 3框架揭秘] Options[1]: 配置选项的正确使用方式[上篇]
依赖注入不仅是支撑整个ASP.NET Core框架的基石,也是开发ASP.NET Core应用采用的基本编程模式,所以依赖注入十分重要。依赖注入使我们可以将依赖的功能定义成服务,最终以一种松耦合的形式注入消费该功能的组件或者服务中。除了采用依赖注入的形式消费承载某种功能的服务,还可以采用相同的方式消费承载配置数据的Options对象。
蒋金楠
2020/02/12
1.1K0
mapboxGL卷帘实现
卷帘对比是webgis中常见的一种对比方式,本文讲述一下如何在mapboxGL中实现卷帘对比。
牛老师讲GIS
2021/09/10
1.8K0
在ListView上使用自定义的Adapter
需要实现的东西是: 一个DataListViewAdapter,当进行如下调用时,就能在列表上显示出数据:
LeoXu
2018/08/15
9700
点击加载更多

相似问题

如何以编程方式在自定义单元格上添加自定义视图?

11

简单产品上的自定义选项无法在订单上显示

31

如何以简单的方式显示加载指示器?

211

简单的Kivy手势(卷帘)

10

如何以简单的方式在Mac上安装gst (gstreamer绑定)?

27
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文