Z and I Emulator for Windows 主机屏幕上的部分 EHLLAPI 输入

问题
使用 HCL Z and I Emulator for Windows 时,将截断的命令文本发送到主机。
原因

如果 EHLLAPI 应用程序向主机发送 SYSREQ 键,然后尝试在主机屏幕上输入命令,则有时只会向主机发送命令的截断部分。出现此问题的原因是 Z and I Emulator for Windows 主机端的 SYSREQ 处理与 EHLLAPI 应用程序的命令输入之间缺乏同步。

当应用程序向主机发送 SYSREQ 命令时,会出现以下情况:
  • OIA 将更新以指示您正在 SSCP-LU 会话中。
  • Z and I Emulator for Windows 会话将 AO 命令 (SYSREQ) 发送到 3270 主机。

一旦主机接收到 SYSREQ,它将使用 0x15 或 NL(换行符)代码响应 Z and I Emulator for Windows。当 Z and I Emulator for Windows 处理此 NL 命令时,使用 NULL 填充行的其余部分,并将光标移到下一行的开头。

当 EHLLAPI 应用程序继续在主机屏幕中输入各种命令(通过 SendKeys 函数)时,甚至在 Z and I Emulator for Windows 会话从主机收到 NL 命令并对其进行处理之前,就会出现问题。因此,首先将输入命令的一部分输入到屏幕上,同时处理 NL 命令并将光标移到下一行。然后在下一行输入命令的其余部分。因此,只有被截断的命令的第二部分被发送到主机,从而导致错误的结果。

分辨率
此问题的解决方法是强制 EHLLAPI 应用程序等待 NL 命令被接收和处理,然后再继续将命令输入主机屏幕。一旦会话通知 EHLLAPI 应用程序 SYSREQ 的主机响应已被处理,EHLLAPI 应用程序就可以继续其输入(因为会话现在处于接受新输入的正确状态)。为此,使用以下 EHLLAPI 函数调用:
Start_Host_Notification (23)
Pause (18)
Set_Session_Parameters (9)
Query_Host_Update (24).
EHLLAPI 应用程序中的可能代码如下所示:
  • 调用 Sendkeys(@A@H)。这会将 SYSREQ 命令发送到会话。
  • 使用输入 B 调用 StartHostNotify,其中 B 表示 OIA 和 PS 的通知。这会告诉会话在主机更新会话的 OIA 和/或 PS 时通知 EHLLAPI 应用程序。
  • 调用暂停,指定足够的超时时间。这会导致 EHLLAPI 应用程序等待,直到会话通知它会话的 OIA 和/或 PS 的主机更新。当会话收到等待时间最长的 SYSREQ 命令主机响应时,就会发生这种情况。请注意,如果超过了超时值,并且未收到主机通知,则仍会返回“暂停”功能调用。

此外,要使此“暂停”调用生效,必须使用 Set_Session_Parameters (9) 功能调用启用 IPAUSE 选项。这是必需的,因为它告诉暂停 API 调用在主机通知会话 OIA 和/或 PS 更新时返回。

如果由于 OIA/PS 更新(主机通知)而返回“暂停”,则返回值为 26。如果是这种情况,则可以发送主机命令。否则,必须再次等待主机响应。

当 EHLLAPI 应用程序知道主机已更新 OIA 或表示空间(或两者)时,它可以继续执行命令。QueryHostUpdate 用于检查更新了哪些内容:即,是仅更新了 OIA(返回码 21),还是仅更新了 PS(返回码 22),还是同时更新了 OIA 和 PS(返回码 23)。

例如,EHLLAPI 代码可能类似于以下部分:
Send Keys(@A@H) /* Send SYSREQ command to the host */

Start Host Notification with 'B' in byte 2 /* Enable notification to EHLLAPI application
                                              when session's OIA and/or PS are updated */

Set Session Parms with IPAUSE option /* Allow Pause to be interrupted */

Label WW:

Pause for 15 seconds /* 15 secs is a sample time-out value */

retVal = Query Host Update /* Store return value of QueryHostUpdate() into retVal */

If (retVal = 21 or 22 or 23) /* OIA and/or PS was updated */

Send Keys("Your Input Command to host") /* Send input command to host */

else

goto (Label WW)

Stop Host Notification /* Disable host notification */ 

这是最适合解决此问题的解决方案,因为 EHLLAPI 应用程序在发送其命令输入之前,等待允许会话接收和处理 SYSREQ 主机响应所需的最短时间。

另一个解决方案是在 EHLLAPI 应用程序中的 SYSREQ 命令和后续命令之间添加一个延迟 [例如,Sleep(1000)],以便会话有足够的时间接收和处理主机响应。但是,这种解决方案不是最好的,因为延迟可能会太短或过长。

有关 3270 SYSREQ 功能的详细信息,请参阅 RFC 2355(TN3270 增强)。