#InterSystems IRIS for Health

0 关注者 · 862 帖子

InterSystems IRIS for Health™ 是全球第一个也是唯一一个专门为医疗应用程序的快速开发而设计的数据平台,用于管理全世界最重要的数据。它包括强大的开箱即用的功能:事务处理和分析、可扩展的医疗保健数据模型、基于 FHIR 的解决方案开发、对医疗保健互操作性标准的支持等等。所有这些将使开发者能够快速实现价值并构建具有突破性的应用程序。了解更多信息

文章 姚 鑫 · 十二月 13, 2024 3m read

第四十九章 终端输入 输出 - 转义序列编程

转义序列编程

转义序列的 ANSI 标准使智能终端的编程变得实用。字符串中转义字符及其后面的所有字符不会显示在屏幕上,但会更新$X$Y 。使用WRITE *语句将转义序列发送到终端,并通过直接设置$X和$Y来保持它们最新。

ANSI 标准建立了转义序列的标准语法。特定转义序列的效果取决于使用的终端类型。

每次READ之后在$ZB中查找传入的转义序列。 IRISANSI 标准转义序列和任何其他使用 ANSI 形式的转义序列放入$ZB中。 IRIS 可识别两种形式的转义序列:

常规形式

  • An ESC.
  • 可选字符“O”(字母),十进制值 79
  • 零个或多个十进制值为 32–47 的字符。
  • 十进制值 48–126 的一个字符。

控制形式

  • ESC字符,十进制值 27
  • “[”字符,十进制值 91
  • 零个或多个十进制值为 48–63 的字符。
  • 零个或多个十进制值为 32–47 的字符。
  • 十进制值 64–126 的一个字符。

此外,序列不能超过 16 个字符。违反这些形式或规则的转义序列设置$ZA的位 8,其值为 256

示例

假设正在对一个终端进行编程,其帮助键发送两个字符序列Escape-? ( ?的十进制值为 63

%SYS>SET HELP=$C(27,63)
ASK READ !,"Enter ID: ",X I $ZB=HELP Do GIVEHELP GoTo ASK

例程可以检测非标准转义序列,如下所示:

  1. ESC成为terminator
  2. 当ESC出现在$ZB中时:
    1. 使用 Secret 协议禁用 echo 以防止修改 $X/$Y
    2. 使用READ *读取序列的其余部分;
    3. 关闭 Secret 以重新启用 echo

在下图中,要求用户输入 ID。如果用户按Esc-? ,出现帮助屏幕。子例程ESCSEQ假定非标准转义序列以星号“*”结尾。

DEMOS 
  SET HELP=$C(27,63) ;Get Help with <ESC>?
    SET ESC=$C(27) USE 0:("":"":ESC) ; Make <ESC> a READ terminator
                                     ; character
ASK READ !,"Enter ID: ",X I $ZB=ESC Do ESCSEQ G:SEQ=HELP ASK 
    . ;Input ID. Handle Help request. 
    .
    Quit
HELPSCR  ;Process Help request 
    . 
    Quit
ESCSEQ  USE 0:("":"S") SET SEQ=ESC ;Set terminal to no echo,init SEQ 
    FOR I=1:1 {
      READ *Y 
      SET SEQ=SEQ_$C(Y)
      QUIT:Y=42 }
    ; Read in Escape sequence, 
    ; end at "*" 
    USE 0:("":"":ESC) Quit ;Redefine terminator

IRIS 支持计算机间链接和特殊设备

IRIS 提供灵活的协议和大型独立缓冲区,使例程能够处理异常设备及其协议。例如, IRIS 可以轻松支持终端到终端链路上两台计算机之间的全双工通信。两个 IRIS 系统仅需要物理连接、正确的协议以及相同的速度、奇偶校验和字符长度设置。借助外部转换器, IRIS 作为同步 EBCDIC 终端与 IBM 端口进行通信。

设计计算机间链路时请记住以下几点:

  • 通过在OPENUSE中包含 S 协议,或者使用操作系统的终端参数来关闭两端的回显。
  • 除非通信协议支持 XON/XOFF 流量控制( Ctrl-QCtrl-S ),否则请确保它将未确认的传输限制在操作系统输入缓冲的限制内;否则可能会丢失数据。
  • 在图像模式下, IRIS 不支持 XON/XOFF。在非图像(正常)模式下,操作系统的终端参数决定如果操作系统的输入缓冲区几乎已满,计算机是否发出 XOFF。如果不支持 XOFFXON,请将缓冲区设置得足够大,以便不需要它们。
  • 读取操作后测试$ZA以检测传输错误,例如奇偶校验或数据溢出情况。
0
0 112
文章 姚 鑫 · 十二月 11, 2024 2m read

第四十七章 终端输入 输出 - DTM PC 控制台的助记符空间

DTM PC 控制台的助记符空间

IRIS 提供 IRIS 例程 %XDTM 来匹配开发 DTM 应用程序时使用的助记符。该助记词空间可用,但未设置为终端默认助记词空间。如果您将为 DTM 创建的应用程序移植到 IRIS,可以:

  • 在管理门户中将 ^%XDTM 配置为终端( MnemonicTerminal )的默认助记词空间,或者
  • OPENUSE命令中引用 ^%XDTM 助记符空间。

DTM 示例

UNIX

  OPEN "/dev/tty04/"::"^%XDTM"

Windows

  OPEN "c:\sys\user"::"^%XDTM"

然后 IRIS 可以正确解释WRITE /mnemonic命令中的 DTM 控制助记符,如下表所示。

DTM PC 控制台的控制助记符

MnemonicDescription
AANormal mode
ABBold mode
ACUnderlined mode
ADBold, underlined mode
AEReverse video
AFReverse video/Bold mode
AGReverse video/Underline mode
AHReverse video/Bold, underlined mode
AIBlink mode
AJBold, blink mode
AKUnderlined, blink mode
ALBold, underlined, blink mode
AMReverse video / Bold, blink mode
ANReverse video / Bold, blink mode
AOReverse video / Underlined, blink modes
APReverse video / Bold, underlined, blink modes
AZMode Z
B(%1,%2)Set video attributes: %1 provides attribute for characters, %2 provides attribute for clearing frames
BOXDraw a window-relative utility box
C(%1,%2)Position cursor at column %1, line %2
CLRClear current frame
COLOR(%1,%2)Set IBM PC Color: Foreground %1, Background %2
DC(%1)Delete %1 characters
EC(%1)Erase %1 characters
EFErase to end of frame
ELErase to end of line
F(%1,%2,%3, %4,%5)Fill rectangular area with $CHAR(%1) at upper left corner, %4 columns wide by %5 lines high
GETCURReturn terminal cursor position
HFScreen half bright off
HIDECURSORHide mouse cursor
HNScreen half bright
IC(%1)Insert %1 characters
LFDisable literal mode
LNEnable literal mode, which displays control characters graphically on a PC screen.
MARK(%1)Make mark on screen
NORMEnable normal display attributes
PAD(%1)Write %1 NULLS for padding
PFPause off
PNPause on
RFScreen reverse video off
RNScreen reverse video
SD(%1,%2,%3)Scroll current frame down by %3 lines
SHOWCURSORShow mouse cursor
SU(%1,%2,%3)Scroll current frame up by %3 lines, starting at line %1 down to but not including line %2
VFVisible cursor off
VNVisible cursor on
WBOXDraw a screen-relative utility box
WCLOSEClose utility window
WINDOWSet scrolling window
WOPENOpen utility window
Y(%1)Set binary frame attribute
0
0 60
文章 姚 鑫 · 十二月 10, 2024 4m read

第四十六章 终端输入 输出 - CLOSE 命令

CLOSE 命令

释放设备的所有权,这是通过OPEN命令获得的。

语法

CLOSE device

终端预定义助记符空间

IRIS 提供了两个预定义的助记符空间供终端使用:

  • ^%X364 用于 ANSI X3.64 终端
  • ^%XDTM 用于 DTM PC 控制台

如果激活这些助记符空间之一,则可以在WRITE /mnemonic命令中使用与它们关联的控制助记符。还可以创建自己的助记符空间。有关助记符空间的更多信息,请参阅使用助记符空间控制设备。

以下部分描述了这些助记符空间的控制助记符。

X3.64的助记符空间

IRISANSI X3.64 定义提供内置助记符空间。该助记符空间是管理器命名空间中的 IRIS 例程 %X364。要使用例程 %X364,请执行以下任一操作:

  • IRIS 系统管理员在IO Settings配置设置中输入 %X364 作为默认助记符空间。从管理门户中,选择“系统管理” 、 “配置” 、 “设备设置” 、 “IO 设置” 。
  • 发出指定此助记符空间的OPEN命令:
 OPEN "terminal"::"^%X364"

下表列出了助记符。

Calling Sequence 调用顺序NameSystem Variable Affected 受影响的系统变量
APC应用程序命令
BELRing the bell
CBT(%1)Cursor Backward Tabulation 光标向后制表$X
CCHCancel Character
CHA(%1)Cursor Horizontal Absolute 光标水平绝对值$X
CHT(%1)Cursor Horizontal Tabulation 光标水平制表$X
CNL(%1)Cursor Next Line 光标下一行$X,$Y $X , $Y
CPL(%1)Cursor Preceding Line 光标前一行$X,$Y $X , $Y
CPRCursor Position Report
CTC(%1,%2,%3,%4, %5,%6,%7,%8,%9)CTC(%1、%2、%3、%4、%5、%6、%7、%8、%9)Cursor Tabulation Control 光标制表控制
CUB(%1)Cursor Backward 光标向后$X
CUD(%1)Cursor Down 光标向下$Y
CUF(%1)Cursor Forward 光标向前$X
CUP(%1,%2)Cursor Position 光标位置$X, $Y $X , $Y
CUU(%1)Cursor Up 光标向上$Y
CVT(%1)Cursor Vertical Tabulation 光标垂直制表$Y
DADevice Attributes 设备属性
DAQ(%1,%2,%3,%4, %5,%6,%7,%8,%9)Define Area Qualification 定义区域资格
DCH(%1)Delete Characters 删除字符
DCSDevice Control String 设备控制字符串
DL(%1)Delete Lines 删除行
DMIDisable Manual Input 禁用手动输入
DSR(%1)Device Status Report 设备状态报告
EA(%1)Erase in Area 擦除区域
ECH(%1)Erase Characters 删除字符
ED(%1)Erase in Display 擦除显示
EF(%1)Erase in Field 在字段中擦除
EL(%1)Erase in Line 在线擦除
EMIEnable Manual Input 启用手动输入
EPAEnd of Protected Area 保护区尽头
ESAEnd of Selected Area 选定区域的末尾
FNTFont Selection 字体选择
GSMGraphic Size Modification 图形尺寸修改
GSSGraphic Size Selection 图形尺寸选择
HPA(%1)Horizontal Position Attribute 水平位置属性$X
HPR(%1)Horizontal Position Relative 水平位置相对$X
HTJHorizontal Tab with Justify 带对齐的水平制表符$X
HTSHorizontal Tab Set 水平制表符集$X
HVP(%1,%2)Horizontal and vertical position水平和垂直位置$X, $Y $X , $Y
ICH(%1)Insert Characters 插入字符
IL(%1)Insert Lines 插入行
INDIndex$Y
INTInterrupt
JFYJustify
MCMedia Copy
MWMessage Waiting
NELNext Line 下一行$X, $Y $X , $Y
NP(%1)Next Page 下一页
OSCOperating System Command 操作系统命令
PLDPartial Line Down 部分线路向下$Y
PLUPartial Line Up$Y
PMPrivacy Message 隐私信息
PP(%1)Preceding Page 上一页
PU1Private Use 1 私人使用1
PU2Private Use 2 私人使用2
QUADQUAD
REP(%1)REPEAT$X, $Y $X , $Y
RIReverse Index 反向索引$Y
RISReset to Initial State 重置为初始状态$X=0 $Y=0 $X =0 $Y =0
RM(%1,%2,%3,%4,% 5,%6,%7,%8,%9)Reset Mode 复位模式
SEMSelect Editing Extent Mode 选择编辑范围模式
SGR(%1,%2,%3,%4, %5,%6,%7,%8,%9)Select Graphic Rendition 选择图形呈现
SLScroll Left向左滚动
SM(%1,%2,%3,%4,% 5,%6,%7,%8,%9)Set Mode 设置模式
SPAStart of Protected Area 保护区的开始
SPISpacing Increment 间距增量
SRScroll Right 向右滚动
SS2Single Shift Two
SS3Single Shift Three
SSAStart of Selected Area 选定区域的开始
STString Terminator 字符串终止符
STSSet Transmit State 设置传输状态
SUScroll Up 向上滚动
TBCTabulation Clear 表格清除
TSSThin Space Specification
VPA(%1)Vertical Position Attribute 垂直位置属性$Y
VPR(%1)Vertical Position Relative 垂直位置相对$Y
VTSVertical Tab Set垂直制表符集
0
0 64
文章 姚 鑫 · 十二月 9, 2024 3m read

第四十五章 终端输入 输出 - WRITE 命令

WRITE 命令

将零个或多个字符写入终端

语法

WRITE *variable 
WRITE *-n
WRITE # 
WRITE /mnemonic
参数定义
(none)不带参数的WRITE将写入当前设备上的所有局部变量。
*variableWRITE *变量写入一个字符,其十进制值等于x 。对于 ASCII 字符,变量的值应为 0255 范围内的整数;对于 Unicode 字符,变量的值应为 >255。按照约定,从 0127 的值表示 7ASCII 字符,而 128255 表示扩展 ASCII 字符集,与应用程序本身相关。如果硬件和软件设置正确, IRIS 可以处理 8 位数据。示例:您可以使用第八位来表示国际字符集。 IRIS 例程通常使用WRITE *来发送设备相关功能的控制字符。示例:WRITE *27,*91,*50,*74 清除终端屏幕。 WRITE *不会更改$X$Y ;假设WRITE *输出高度特定于输出设备。
*-1*-1会清除输入缓冲区。它清除等待下一个READ命令的所有字符。因此,所有预先输入的字符都被清除。
输入缓冲区保存从键盘到达的字符,甚至是您在例程执行READ命令之前键入的字符。因此,甚至可以在问题出现在屏幕上之前就回答问题。当READ命令从缓冲区获取字符时, IRIS 将它们回显到终端,以便问题和答案一起出现。当例程检测到错误时,它可能会发出WRITE *-1来取消这些答案。
*-10WRITE *-10立即清除输入缓冲区。它不会等待下一个READ命令。因此,它会清除WRITE *-10之前发出的所有预输入字符;在WRITE *-10之后发出的预输入字符保留在输入缓冲区中,供下一个READ使用。
#CRT 终端发出WRITE #会清除屏幕并将光标发送到起始位置 (0,0)。对于硬拷贝终端,它写入回车符和换页符。 WRITE #$Y设置为 0。
`/mnemonic发出WRITE /mnemonic会使 IRIS 解释活动助记符空间中定义的助记符。如果没有活动的助记符空间,则会产生错误。您可以通过两种方式指定活动助记符空间: 通过使用命名空间和网络配置编辑器为每种设备类型命名默认助记符空间,通过在设备的OPENUSE`命令中指定助记符空间。有关更多信息,请参阅使用助记符空间控制设备。

示例

在以下示例中, WRITE *在用户终端上响铃,显示提示,并清除输入缓冲区中已接收但尚未使用的所有字符。

   SET eek="No. I can't accept that reply" 
   WRITE *7,eek,*-10

以下两个示例显示了WRITE *-1WRITE *-10之间的区别。在这两种情况下,用户都会响应第一个READ并按 ENTER,然后在HANG命令导致的两次暂停期间向前键入:

  READ "type:",x HANG 4 WRITE *-1 HANG 4 READ "type:",y

在上面的示例中,当发出第二个READ时, IRIS 会清除输入缓冲区。因此,在任一挂起期间键入的任何文本都会从缓冲区中清除。

  READ "type:",x HANG 4 WRITE *-10 HANG 4 READ "type:",y

在上面的示例中,当发出WRITE *-10时, IRIS 立即清除输入缓冲区。因此,在第一次挂起期间键入的任何文本都会被清除,但在第二次挂起期间键入的任何文本都将提供给第二个READ命令。

在以下示例中, WRITE /mnemonic使用控制助记符 CUP(CUrsor Position)将光标移动到终端上第四行的第三列。在本例中,在USE命令中指定了预定义的助记符空间^%X364,并使用terminal变量指定了打开的终端设备的名称。有关 ^%X364 的说明,请参阅终端的预定义助记符空间。

   USE terminal:(80:"BP"):"%X364"
   SET %1=3,%2=4
   WRITE /CUP(%1,%2)
0
0 60
文章 姚 鑫 · 十二月 8, 2024 3m read

第四十四章 终端输入 输出 - 特殊协议字符影响终端 I O

特殊协议字符影响终端 I O

每个操作系统都会拦截某些协议字符 (UNIX) 或组合键(例如 Windows 平台上的CTR-ALT-DEL ),以防止这些字符影响 IRISWindows 控制台不会尝试覆盖这些操作系统特征。

其他特殊字符可以改变例程的执行方式,但不会出现在READ命令变量中。在图像模式下操作终端会取消这些效果,并使 IRIS 像对待任何其他字符一样对待这些字符。

READ受输出和输入控制字符的影响。 READ只是读取除终止字符之外的所有其他控制字符。它不回应他们。

输出控制字符影响例程的流程和输出。下表对此进行了描述:

输出控制字符

输出控制字符十进制值定义
Ctrl-C3如果启用了中断,则Ctrl-C会中断例程的执行。该例程的行为就像发生错误。如果禁用中断,则Ctrl-C会导致 IRIS 丢弃当前READ中迄今为止输入的任何内容。可以使用Ctrl-C中断需要网络操作的全局模块请求。要捕获Ctrl-C ,请设置特殊变量$ZTRAP 。有关其他信息,请参阅有关启用中断的部分。
Ctrl-S19Ctrl-S暂停到终端的输出。当 IRIS 遇到Ctrl-Q时,终端输出将恢复。
Ctrl-Q17Ctrl-Q恢复由Ctrl-S暂停的输出。

输入控制字符影响输入。图像模式(I 协议)将这些字符视为数据,但在正常模式下它们会影响当前READ命令的输入。这些字符的描述如下表所示:

输入控制字符

输入控制字符小数值定义
Delete127删除字符删除最后输入的字符。如果重复按 Delete 键,则会从右向左删除字符,但不会超出当前READ的开头。删除使用退格键删除 CRT 屏幕上的最后一个字符。在打印终端(例如电传打字机)上以反斜杠字符(“\”)形式删除回显。
Ctrl-U21删除自当前READ开始以来输入的所有字符或 UNIX 预输入缓冲区中直到最后一个回车符的内容。 Ctrl-U擦除 CRT 上删除的字符;在打印机上,它会回显 ^U 并发送 ReturnLineFeed 要完全刷新预输入缓冲区,请使用Ctrl-X
Ctrl-H8在某些系统上执行与删除相同的功能。
Return13在除“I”(图像模式)之外的所有协议中,回车都会结束READ
Escape27开始转义序列。序列本身结束READ ,并且$ZB包含完整序列,包括前导 EscapeIRIS 不会回显序列中的字符,但它会更改$X$Y,除非在WRITE *命令中包含转义序列。请参阅本页前面的$X$Y 以及光标位置。无效的转义序列设置$ZA的位 8。考虑这个例子, READ X。输入字符“AB”Escape“E”后, X将包含两个字符“AB”,而$ZB包含两个字符 Escape E$X对于AB会增加 2,但对于 $ZB 则不会增加E。
LineFeed10IRIS 将 LineFeed 解释为所有终端 I/O 的终止符。
Tab9Tab 是一个数据值,它显示为空格,将$X加一,并作为 Tab 字符存储在READ返回的字符串中。对于除“T”(终止符)之外的所有协议都是如此。在“T”协议中,制表符是终止符控制字符。

禁用 UNIX® 作业控制

在 IRIS 中使用 UNIX® 作业控制字符Ctrl-Z可能会导致严重问题。因此,当在 UNIX® shell 支持作业控制的平台上进入 IRIS 时, IRIS 会自动禁用Ctrl-Z 。当退出 以及发出$ZF(-1)调用来执行 UNIX® shell 命令时, IRIS 会重新启用Ctrl-Z

READ 命令如何处理输入

READ命令处理从输入缓冲区到达的每个字符。下表显示了正常模式下如何进行此处理。下图显示了READ命令如何处理图像模式数据。

0
0 74
文章 姚 鑫 · 十二月 7, 2024 2m read

第四十三章 终端输入 输出 - READ 命令

Read 命令

从键盘读取 032 KB 的内容到指定变量中。超时参数是可选的。该命令不能以井号 (#) 或冒号 (:) 结尾

语法

READ variable:timeout                                             ; Variable-length read
READ variable#length:timeout  ; Fixed-length read
READ *variable:timeout                                           ; Single-character read

示例

下表提供了如何使用这些参数的几个示例。

READ 命令参数:示例

例子影响
READ ^GLO从当前设备读取字符,直到找到终止符,并将结果字符串放入全局^GLO中。
READ X:60从当前设备读取,直到找到终止符,并将读取的字符串放入变量X中。在超时之前最多等待 60 秒输入结束。敲击按键不会重置超时值。
READ *X从当前设备读取单个字符并将其十进制值放入局部变量X中。
READ X#1从当前设备读取单个字符并将其字符串值放入局部变量X中。
READ X#45:60从当前设备读取最多 45 个字符并将字符串值放入局部变量X中。在超时之前最多等待 60 秒输入结束。

Read取行调用

读取行调用模式提供可编辑行的行调用,作为来自终端的READ操作的输入。这些可调用行包括先前的READ输入行和先前的命令行。输入行的回显是读取行调用的必要前提。

IRIS 支持可变长度终端读取 ( READ 变量) 和固定长度终端读取 ( READ 变量#length ) 的读取行调用。 IRIS 不支持单字符终端读取 ( READ *varaiable ) 的读取行调用。读取行调用支持可选的超时参数。

对于固定长度的终端读取,调用的行将被截断为比READ中指定的字符数少一个字符。最后一个READ字符位置保留用于键入行终止字符、指定编辑字符或添加另一个数据字符。

当读取行调用处于活动状态时,可以使用向上箭头和向下箭头键向READ提供输入,以调用先前的终端输入行。然后,可以使用向左箭头、向右箭头、 HomeEnd键定位光标以编辑调用的行。可以使用Backspace键删除字符,使用Ctrl-X删除整行,或使用Ctrl-U删除光标左侧的所有行。

当读取行调用未激活时,四个箭头键、 Home键和End键都会发出行终止字符。可以使用Backspace键删除单个输入字符,使用Ctrl-X (或Ctrl-U )删除整个输入行。

可以使用OPENUSE命令通过指定 R 协议来激活读取行调用,或通过指定 NIST 协议来停用读取行调用。

0
0 81
文章 姚 鑫 · 十二月 6, 2024 2m read

第四十二章 终端输入 输出 - 显式终止符

显式终止符

OPENUSE命令中的终止符参数允许您将特定字符定义为READWRITE命令的终止符。这些显式终止符可用于补充指定协议提供的终止符字符。终止符参数还可用于覆盖协议对字符的指定,并将其指定为终止符。将字符重新定义为终止符的能力的例外情况是:ASCII 0 (NULL)ASCII 3 ( Ctrl-C ) 以及两个输出控制字符Ctrl-Q (XON)Ctrl-S (XOFF)。它们保留其功能,并且不能重新定义为终止符。

示例

此示例将 ZBackspaceTab定义为主设备的终止符。下划线是连接运算符。

  USE 0:("":"":"Z"_$CHAR(8,9))

通过对无主终端发出OPEN命令,您可以隐式清除 IRIS 内部显式终止符列表。当出现协议字符串时, IRIS 会执行以下操作:

  1. 清除其显式终止符列表。
  2. 根据协议字符串设置协议。
  3. 将终止符字符串(如果有)复制到显式终止符的内部列表中。

下表给出了显式终止符字符串的示例。

Terminator String 终止符字符串Definition 定义
USE 0:(80:"C":$CHAR(27))转义字符终止READ,而不是开始转义序列。
USE 0:(80:"C":"")空字符串清除所有终止符。
USE 0:(80:"C")指定协议时省略终止符参数将清除所有终止符。
USE 0:(80) or U 0:80省略协议和终止符会使终止符保持不变。

读操作中的协议和终止符总结

以下字符结束正常(非图像)模式READ

  • Enter
  • 终止符字符串中除 ASCII NUL 以及字符Ctrl-C Ctrl-OCtrl-QCtrl-S之外的任何字符。
  • T 协议生效时,除了输出控制字符之外的任何控制字符。控制字符是十进制值 031 127159 的非打印字符。
  • 任何转义序列。
  • 固定长度READ x#y的字符编号y

以下字符结束图像模式READ

  • 终止符字符串中指定的任何字符(ASCII NUL 除外)。
  • T 协议生效时,任何控制字符。
  • 固定长度READ x#y的字符编号y 。
0
0 80
文章 姚 鑫 · 十二月 5, 2024 3m read

第四十一章 终端输入 输出 - 协议终止符

协议终止符

OPENUSE 协议定义了哪些 READ 输入字符、控制序列和击键被视为隐式终止符。这四种协议是 I(图像模式)、N(正常模式(默认))、R(读取行调用模式)和 T(终止符模式):

  • I(图像模式)接受所有 256 个八位字符作为数据,不将任何字符视为 READ 输入终止符或命令行编辑字符。因此,您应该在图像模式下仅使用单个字符或固定长度的READ操作。如果没有定义终止字符,普通的READ会导致错误。
  • N(普通模式)和 C(CRT 模式)接受除以下六种字符之外的所有字符作为数据:ASCII 3、8、10、13、21 和 127。其中两种字符:ASCII 10(换行符)和 13(回车符)终止 READ 并提交输入。 ASCII 3 ( Ctrl-C ) 丢弃输入并发出如果启用 BREAK,则会出现错误。 ASCII 8(退格)和 127(删除)执行单字符退格擦除,然后继续读取。 ASCII 21 执行多字符退格,擦除所有先前的字符,然后继续读取。
  • R(读取行调用模式)接受除以下 20 种以外的所有字符作为数据:ASCII 1 到 8、10 到 14、16、18、21、23、24、27 和 127 ASCII 10(换行)和 13(回车) return) 终止 READ 并提交输入。 ASCII 3 ( Ctrl-C ) 丢弃输入并发出如果启用了 BREAK。其他字符执行以下命令行编辑功能:
1   ^A = beginning of line
2   ^B = back word
3   ^C = interrupt
4   ^D = delete current character
5   ^E = end of line
6   ^F = forward word
7   ^G = delete to beginning of word ("wipe word backward")
8   ^H = BS = destructive backspace
9   ^I = HT = horizontal tab (echoed as a SPACE)
10  ^J = LF = end of input
11  ^K = VT = forward character
12  ^L = FF = erase to end of line
13  ^M = CR = end of input (same as LF)
14  ^N = recall next input line
16  ^P = recall previous input line
18  ^R = back char (reverse)
21  ^U = erase to start of line
23  ^W = delete to end of word "gobble word forward")
24  ^X = erase entire line
27  ESC lead character for arrow and function keys
127 DEL = destructive backspace (same as BS)
  • T(终止符模式)接受除 65 个控制字符之外的所有字符作为数据:ASCII 031ASCII 127159。这些字符中的大多数被视为 READ 终止字符。这包括制表符 (ASCII 9),它在所有其他协议中被视为数据字符。一些字符被视为命令行控制字符: ASCII 3 ( Ctrl-C ) 丢弃输入并发出如果启用了 BREAKASCII 8(退格)和 127(删除)执行单字符退格擦除,然后继续读取。 ASCII 21 ( Ctrl-U )ASCII 24 ( Ctrl-X ) 执行多字符退格,擦除所有先前的字符,然后继续 READ ASCII 27 是转义字符。
  • IT(图像模式 + 终止符模式)接受除 65 个控制字符之外的所有字符作为数据:ASCII 031ASCII 127159。它将所有控制字符视为 READ 终止符。

在任何这些模式中,都可以使用terminator参数显式指定其他终止符。由于图像模式通常用于位流数据,因此通常避免指定任何字符作为终止符。

0
0 91
文章 姚 鑫 · 十二月 4, 2024 5m read

第四十章 终端输入 输出 - 用于OPEN和USE的字母代码协议

用于OPEN和USE的字母代码协议

特殊情况或终端可能需要不同的协议。使用协议字母代码参数(或相应的关键字参数),可以更改 IRIS 与终端通信的规则。协议对正常读取和单字符读取的影响是一样的。

禁用所有特殊协议的正常模式足以满足大多数终端 I/O 的需要。在正常模式下,IRIS 会回显每个传入的 ASCII 字符,并将其发送回以显示在终端上。 Return或有效的转义序列结束READ命令。

对终端发出OPEN会关闭所有先前的协议,除非您使用 +- 选项。

下表描述了有效的协议字符及其效果。

用于开放和使用的字母代码协议

协议字符姓名定义
BBREAK如果启用了中断 (+B),则Ctrl-C将中断正在运行的例程并使用错误。如果禁用中断 (-B),则Ctrl-C不会引起中断,并且不会显示“^C”。该协议的使用取决于登录模式默认建立的BREAK命令,如下:
如果以程序员模式登录,则始终启用中断 ( BREAK 1 )。 OPENUSE命令中指定的 B(或 /BREAK)协议无效。
如果以应用程序模式登录,则默认为BREAK 0 ,并且可以通过OPENUSE命令中指定的 B(或 /BREAK)协议来启用或禁用中断。
CCRT terminalC 模式接受所有八位字符作为数据,但以下六位字符除外:ASCII 3、8、10、13、21 和 127ASCII 127 删除字符回显为破坏性退格,即退格并擦除前面的字符特点。 ASCII 21 ( Ctrl-U ) 回显足够的破坏性退格键,将光标移至READ的开头。如果右边距的设置或终端的性质强制回显字符开始新行,则Ctrl-U只能删除最后一个物理行上的字符。在任何情况下, Ctrl-U都会取消自READ开始以来的所有输入。 CP 协议互斥。
FFlush在每次READ之前刷新(清空)输入缓冲区。可以刷新输入缓冲区以禁止用户在终端上的READ操作之前键入,因为 IRIS 会丢弃READ操作之间键入的任何内容。请注意,无论 F 协议如何,命令WRITE *–1都会随时刷新输入缓冲区。
IImage modeI 模式接受所有 256 个八位字符作为数据,不将任何字符视为 READ 终止符,除了在终止符参数中明确指定的终止符(如果有)之外。如果没有显式指定终止字符,则应仅使用单个字符和固定长度的READ操作。如果没有定义终止字符,普通的READ将导致 <TERMINATOR> 错误。
图像模式(I)协议可以与其他协议字符组合。在图像模式下,IRIS 忽略协议字符 PCB。在图像模式下,协议字符 F、N、R、S 和 T 仍然有效。当不处于图像模式时,设备处于 N(正常)模式。
K\name\I/O Translation Mode当对设备使用 K 协议时,如果已在系统范围内启用转换,则该设备将发生 I/O 转换。您可以通过指定表的名称来标识转换所基于的先前定义的表。 (较旧的形式 Knum,其中“num”表示加载表的槽号,已被淘汰,但仍受支持。)
NNormal modeN 模式接受所有八位字符作为数据,但以下六位字符除外:ASCII 3、8、10、13、21127。这些隐式终止符和命令行编辑控制字符将在本页后面介绍。如果启用 R(读行重调用)协议,则 N 禁用 R 协议。如果未指定协议值,则此模式为默认模式。
PPrint device 打印装置ASCII 删除字符回显为反斜杠 (\), Ctrl-U回显为“^U”,后跟回车符和换行符。当您对终端发出OPEN命令时,IRIS 自动调用协议 C 或 P,具体取决于操作系统终端设置。这些协议将一直有效,直到您明确更改设备的协议为止。既不包含 C 也不包含 P 的协议字符串不会取消该协议。
R启用读取行调用模式R 协议启用该设备的读取行调用模式。要激活当前进程的读取行调用,请使用 LineRecall() 。 R 协议会覆盖指定设备的这些默认设置。要更改已打开设备的读取行调用,必须向该设备显式指定另一个OPEN命令。通过指定 N 协议禁用读取行调用。
SSecret inputREAD上没有任何回声。 READ命令不会更改$X$Y 。读取行调用被禁用。
TTerminatorT 模式不将任何控制字符视为数据。以下是控制字符:十进制值从 031127159ASCII 字符。这些控制字符中的大多数被视为 READ 终止符。以下控制字符除外,它们执行其他控制操作:ASCII 3 ( Ctrl-C )、ASCII 8 (退格键)、ASCII 17 ( Ctrl-Q )、ASCII 19 ( Ctrl-S )、ASCII 21 ( Ctrl-U ) )、ASCII 24 ( Ctrl-X )、ASCII 27 (ESC) 和 ASCII 127 (DEL)
T 模式与 I 模式(IT 协议)组合时,所有控制字符(ASCII 0 31127159)均被视为 READ 终止符,但输出控制字符Ctrl-Q (XOFF)Ctrl- S (XON),以及输入控制字符Ctrl-HCtrl-Y 。输出控制字符Ctrl-QCtrl-S会被大多数终端拦截,即使在 IT 模式下也不会终止READ
UUpcase modeU 模式将所有输入字母转换为大写。
Y\name\$X/$Y Action Mode $X/$Y当对设备使用 Y 协议时,系统使用名为 $X/$Y 操作表。可以通过指定表名称来识别先前定义的用于转换的 $X/$Y 操作表。 $X/$Y 操作始终启用。如果未指定 Y 并且未定义系统默认值 $X/$Y,则使用内置的 $X/$Y 操作表。 + 选项适用于打开 Y 协议,但 - 选项则无效。为了禁用 $X/$Y 关联,可以发出命令: USE0:(:"Y0") (旧形式 Ynum,其中`num``表示表加载到的槽号,正在分阶段进行已退出,但仍受支持。)

协议字符串示例

以下一系列示例展示了协议字符串的功能。以下每个 USE 命令都建立在前面的 USE 命令建立的协议之上:

   USE 0:(80:"BP" )

字母代码 BP 打开 BP 协议。此示例启用中断 (B) 并告诉 InterSystems IRIS 将终端视为打印设备 (P)。

   USE 0:(80:"P")

当它跟在上例中的USE命令之后时,该命令使 P 协议保持有效,但关闭 B 协议。

   USE 0:(80:"+R" )

+R 打开读行调用,不影响其他协议设置。

   USE 0:(80:"")

空字符串关闭所有协议。然而,PC 协议仍然有效。

   USE 0:(80)

省略协议参数会使协议和显式终止符保持不变。

0
0 83
文章 姚 鑫 · 十二月 3, 2024 4m read

第四十章 终端输入 输出 - OPEN 和 USE 命令的关键字参数

OPENUSE 命令的关键字参数

下表描述了使用OPENUSE命令控制终端设备的关键字参数。对于每个关键字,该表列出了OPENUSE相应的字母代码协议。有关使用这些协议的其他信息可以在字母代码协议表中找到。

终端设备的 OPENUSE 关键字参数

关键词默认字母代码协议描述
/BAUD=n/BAUD= n设置端口的调制解调器波特率。支持的值取决于操作系统支持。 /SPEED/BAUD 的别名。
/BREAK[=n] /BREAK[= n ]0B/BREAK 或 /BREAK= n (对于n的非零值)启用协议。 /BREAK= n如果n值为零,则会禁用协议。
/COMPARAMS=str对应于portstate位置参数。 (此关键字提供了一种以与位置无关的方式指定 COM 端口状态字节代码字符串的方法。)可以包含在str中的端口状态字节代码列在本页前面的表中。
/COMPRESS=str""指定流数据压缩类型。可以启用 ZLIBZSTD 压缩类型。可以指定/COMPRESS=""来禁用压缩。 /COMPRESS="zlib"相当于/GZIP=1 。要压缩字符串,请使用 %SYSTEM.Util.Compress().
/CRT[=n]取决于操作系统终端设置C和PCP 协议相关。 /CRT 或 /CRT= n ( n为非零值)启用 C 协议并禁用 P 协议。 /CRT= n如果n值为零,则会禁用 C 协议并启用 P 协议。
/DATABITS=n设置串行端口的数据位数。有效值为 5、6、78
/DISCONNECT对应于端口状态位置参数的第一个字节。 /DISCONNECT 断开(挂起)COM 端口。它不会关闭端口;可以再次拨出,而无需重新打开 COM 设备。
/ECHO[=n]1S//ECHO/ECHO= n对于n的非零值禁用协议。 /ECHO= n如果n值为零则启用协议。
/EDIT[=n]0R and/EDIT/EDIT= n (对于n的非零值)启用 R 协议并禁用 N 协议。 /EDIT= n如果n值为零,则会禁用 R 协议并启用 N 协议。
/FLOW=str指定用于串行端口的流控制类型。有效值为 NONEXON。某些操作系统还支持 RTSCTS
/FLUSH[=n]0F/FLUSH/FLUSH= n (对于n的非零值)启用协议。 /FLUSH= n如果n值为零则禁用协议。
/GZIP[=n]1指定与 GZIP 兼容的流数据压缩。 /GZIP /GZIP= n (对于n的非零值)启用写入压缩和读取解压缩。 /GZIP=0 禁用压缩和解压缩。在发出 /GZIP=0 以禁用压缩和解压缩之前,请检查$ZEOS特殊变量以确保没有正在进行流数据读取。 /GZIP 压缩对 I/O 转换没有影响,例如使用 /IOTABLE 建立的转换。这是因为压缩是在所有其他转换(加密除外)之后应用的,而解压缩是在所有其他转换(加密除外)之前应用的。
/IMAGE[=n]0I /IMAGE /IMAGE= n (对于n的非零值)启用协议。 /IMAGE= n如果n值为零,则会禁用该协议。
/IOTABLE[=name]如果未指定名称,则使用设备的默认 I/O 转换表。对应K\name\协议,为设备建立I/O转换表。
/MARGIN=n0(无边距)对应margin位置参数,设置终端设备的右边距。
/MODE=n无默认值根据n的值重置协议并设置终端模式。n =0LFESC 设置为默认终止符。n =1 与模式0相同,使能S协议。n =2 与模式0相同,启用T协议。
/NOXY [=n]0$X$Y 处理: /NOXY/NOXY= n (对于n的非零值)禁用 $X$Y 处理。这可以显着提高读取和写入操作的性能。 $X$Y 变量的值是不确定的,并且保证金处理(取决于 $X)被禁用。 /NOXY=0 启用$X 和$Y 处理;这是默认设置。
/OBUFSIZE=nnn256指定终端输出缓冲区的大小(以字节为单位)。增加输出缓冲区大小可以提高在高延迟的广域网上使用 telnet 进行屏幕绘制的性能。/OBUFSIZE 的有效值为 25665536。默认值为 256
/PARAMS=str无默认值对应于协议位置参数。 (此关键字提供了一种以与位置无关的方式指定协议字母代码字符串的方法。)有关可以包含在str中的字母代码表,请参阅字母代码协议。
/PARITY=str指定串行端口的奇偶校验检查类型。有效值为无、偶数、奇数。有些操作系统还支持 MARKSPACE
/SPEED=n/SPEED 是 /BAUD 的别名。
/STOPBITS=n设置串行端口的停止位数。有效值为 12
/TERMINATOR=str无默认值对应于终止符位置参数,该参数建立用户定义的终止符。要编写str ,请参阅使用终止符结束 I/O 操作。
/TPROTOCOL[=n]0T/TPROTOCOL/TPROTOCOL= n对于n的非零值启用协议。 /TPROTOCOL= n如果n值为零,则会禁用协议。
/TRANSLATE[=n]1K/TRANSLATE/TRANSLATE= n (对于 n 的非零值)启用设备的 I/O 转换。 /TRANSLATE= n如果 n 值为零,则会禁用设备的 I/O 转换。
/UPCASE[=n]0U//UPCASE/UPCASE= n (对于 n 的非零值)启用协议。 /UPCASE= n如果n值为零,则会禁用该协议。
/XYTABLE[=name]如果未指定名称,则使用设备的默认 $X/$Y 操作表。Y\name\对应Y\name\协议,为设备建立$X/$Y动作表。

测试 OPEN 命令是否成功

要确定OPEN命令是否成功,您的代码应测试$TEST/$ZE 。仅当使用超时参数指定OPEN命令时才会设置$TEST 。一个仅当Ctrl-C断OPEN命令时才会发生错误。因此,代码不得依赖于错误。

0
0 79
文章 姚 鑫 · 十二月 2, 2024 4m read

第三十九章 终端输入 输出 - terminator

terminator

第三个位置参数:最多八个字符的字符串,其中任何一个都将终止READ 。这些终止符是协议中内置终止符的补充。请参阅使用终止符结束 I/O 操作。

portstate

4 个位置参数:按位置顺序最多包含 8 个字节的字符串,用于控制 COM 端口状态。端口状态字节如下(字节从1开始按从左到右的顺序编号):

Byte 字节意义Values
1Disconnect 断开D=断开(挂断)端口。空白=不断开端口。
2Modem Control 调制解调器控制1=使用调制解调器控制。0=不使用调制解调器控制。空白=调制解调器控制没有变化。
3Data Bits 数据位5=五个数据位。 6=六个数据位。 7=七个数据位。 8=八个数据位。空白=数据位设置没有变化。
4Parity 平价0=无奇偶校验。 1=奇校验。 2=偶校验。 3=标记奇偶校验。 4=空间奇偶校验。空白=奇偶校验设置没有更改。
5Stop Bits 停止位1=一个停止位。 5=1.5 个停止位。2=两个停止位。空白=停止位设置没有变化。
6Flow Control 流量控制X=使用Xon/Xoff流量控制。 C=使用CTS/RTS流量控制。 D=使用DSR/DTR流量控制。 N=禁用流量控制。空白=不改变流量控制。
7DTR Setting 数据传输设置0=禁用 DTR(将其设置为关闭,保持关闭)。 1=启用 DTR(将其设置为打开,保持打开)。空白=DTR 状态没有变化。
8$ZA Error Reporting $ZA 错误报告0=禁用 $ZA 错误报告(默认)。 1=启用 $ZA 错误报告。空白=$ZA 错误报告没有变化。

以下示例显示 COM 端口状态字符串:

  OPEN "COM2":(:::" 0801x0")

字符串值为: 空白(不断开端口); 0(不使用调制解调器控制); 8(八个数据位); 0(无奇偶校验); 1(一个停止位); X(使用Xon/Xoff流量控制); 0(禁用 DTR);默认值(禁用 $ZA 错误报告)。

Disconnect参数通过降低 DTR 信号两秒然后恢复来在调制解调器控制的端口上执行挂断。断开连接不会关闭端口;断开连接后,您可以再次拨出,而无需重新打开 COM 设备。

调制解调器控制参数决定 IRIS 如何响应 RLSD(接收线路信号检测器)引脚(也称为 DCD(数据载波检测))的状态。如果线路受调制解调器控制(调制解调器控制=1IRIS 会监视 RLSD 的状态,并生成一个如果在载体不存在时发出READ命令,则会出现错误。当载波不存在时发出WRITE命令时,IIRIS 不会生成错误。这是因为在建立连接之前必须能够将拨号命令发送到调制解调器。 IRIS 调制解调器控制可以随时启用 (1) 或禁用 (0)。建议在向调制解调器发送命令时禁用调制解调器控制,然后在检测到运营商并建立连接后启用调制解调器控制。

DTR 设置参数用于控制从连接的调制解调器登录。如果 DTR 设置为 0(零),则 DTR 控制信号关闭,调制解调器无法与计算机通信。这可以防止发生拨入连接。如果 DTR 设置为 1(一),则 DTR 控制信号打开,调制解调器可以与计算机通信。可以发生拨入连接。如果将 DTR 配置为关闭 (0),则必须使用OPEN命令或USE命令将其设置为打开 (1),才能使用连接的调制解调器拨出。在大多数情况下,当使用零调制解调器电缆直接连接到终端设备或串行打印机时,DTR 设置并不重要。这是因为零调制解调器电缆应强制 DTR 控制引脚打开。

$ZA 错误报告参数允许将调制解调器控制引脚的状态报告给$ZA特殊变量。无论 COM 端口的调制解调器控制字节设置如何,都可以完成此检查。如果启用 $ZA 错误报告,则可以通过调用 Windows ClearCommError() 函数来清除 COM 端口错误。端口错误状态在$ZA1622 中报告。有关$ZA位值的表,请参阅《 ObjectScript 参考》中的$ZA

baud

5 个位置参数:一个整数值,指定所需的 COM 端口波特率。支持以下波特率:110、300、600、1200、4800、9600、14400、19200、38400、56000、57600、115200、128000、256000

0
0 77
文章 姚 鑫 · 十二月 1, 2024 3m read

第三十八章 终端输入 输出 - USER命令

USER命令

使指定终端成为当前设备。在编程器模式下,同一行代码上的所有后续 I/O 命令都引用该设备。在应用程序模式下,您在USE命令中命名的设备将一直保留为当前设备,直到下一个USE命令为止。

USE 语法

USE命令采用以下参数:

USE terminal:(margin:protocols:terminator):"mnespace"

终端参数可以是一个表达式,其值为终端设备的名称。零 (0) 是该进程的主要设备。 $IO是当前设备。终端的最大长度为 256 个字符。

参数由冒号 (:) 分隔。如果省略参数,则必须指定冒号。命令或其参数列表不得以冒号结束。

可选参数列表包含在括号中,可以包含margin protocolsterminator参数。可以将可选的marginportsterminator参数指定为位置参数(按所示顺序),或使用语法 /KEYWORD=value 指定为关键字参数。关键字参数可以按任意顺序指定;由于 IRIS 按从左到右的顺序执行参数,因此在某些情况下,参数之间的交互可能决定首选顺序。可以在同一参数列表中混合位置参数和关键字参数。如果指定多个参数,则需要使用括号。

要使用USE命令指定 COM 端口状态和波特率,请使用适当的关键字参数。

在参数列表(或占位符冒号,如果未指定参数列表)后面,可以指定一个可选的mnespace参数,该参数标识一个 ObjectScript 例程,其中定义了与WRITE /mnemonic一起使用的控制助记符。

OPEN 和 USE 命令的位置参数

以下位置参数可用于OPENUSE命令。\可以在OPENUSE命令中为设备设置这些参数,或者采用管理门户中配置的默认值。这些参数是位置参数;如果省略参数,则必须包含其前面的冒号作为占位符。

margin

第一个位置参数:一个整数值,指定右边距(以及每行的字符数)。 1255 之间的值设置输出的右边距;任何其他值都会禁用右边距。空字符串使边距设置保持不变。在Windows平台上,不能使用“:n”来控制使用的打印边距。 IRIS 会忽略此类符号。代码如“|PRN| :121” 被忽略。要控制打印机宽度,请发送适合该打印机的控制字符。该符号在其他平台上也适用。

各种终端类型的默认边距在管理门户中定义。选择系统管理、配置、设备设置、设备子类型。当您单击每个列出的设备子类型的“编辑”时,它会显示“右边距:默认”选项。

protocols

第二个位置参数:用引号括起来的一串字母代码字符(例如“BNFU”),其中每个字母启用终端的通信规则之一。字母代码不区分大小写。字母代码可以在任何顺序;由于 IRIS 按从左到右的顺序执行它们,因此字母代码之间的交互在某些情况下可能会指定首选顺序。有关字母代码表,请参阅字母代码协议。

前面的加号或减号会影响协议,如下所示:

  • 前面没有加号或减号:新字符串替换先前的协议字符串。
  • 加号 (+) 位于字母代码字符串之前:新字符串中的协议将添加到先前的协议字符串中。
  • 字母代码字符串前加减号 (-):新字符串中的协议被关闭,但其他协议仍然有效。

用于打开和关闭协议的 + 选项在 DSM-11 兼容模式下不可用。

0
0 71
文章 姚 鑫 · 十一月 30, 2024 3m read

第三十七章 终端输入 输出 - $ZB 显示结束读取的内容

$ZB 显示结束读取的内容

$ZB显示当前设备上最后一次READ操作结束的字符序列或事件。不能设置$ZB ;每次执行READ时,IRIS 都会设置$ZB的值。可以使用此值来作用于不可打印的字符,例如向上箭头键或功能键。

$ZB可以包含以下任意内容:

  • 终止符,例如回车符
  • 转义序列
  • 固定长度READ x#y的字符数y
  • READ *x的单个字符
  • 定时读取过期后出现空字符串

$ZB永远不会包含超过 64 个字符。较长的转义序列无效。

$ZB 示例

以下示例将用户指定的输入字符分配给READ命令变量x ,并将输入终止符(通常是 Return 字符)分配给$ZB特殊变量。从终端提示符发出此命令时,您需要设置一个变量以在与READ命令相同的命令行上捕获$ZB的值。这是因为用于发出命令行的行返回被写入$ZB作为终止符。此示例使用ZZDUMP显示$ZB捕获的字符的值。

USER>READ x SET y=$ZB
USER>ZZDUMP y

0000: 0D 
USER>

OPEN and USE 命令

OPEN 命令

建立终端的所有权。可选参数列表可以设置右边距、指定设备协议以及指定一个或多个终止字符。在参数列表之后,可以选择指定超时参数和/mnespace参数。 mnespace参数指定 IRIS 例程,其中定义了与WRITE/mnemonic一起使用的控制助记符。

OPEN会暂停该过程,直到系统完成打开设备。如果按Ctrl-C中断OPEN命令,则会出现错误结果。

除非指定超时,否则OPEN会保留控制权,直至设备打开完成。超时后,如果 IRIS 无法在指定的秒数内打开设备,则会将$TEST设置为 0 并将控制权返回给进程。即使设备在操作系统级别不可用, OPEN也会继续尝试获取该设备,直到成功或超时到期。

OPEN 语法

OPEN命令采用以下参数:

OPEN terminal:(margin:protocols:terminator:portstate:baud):timeout:"mnespace"

仅需要终端参数。终端参数可以是一个表达式,其值为终端设备的名称。零 (0) 是该进程的主要设备。 $IO是当前设备。终端的最大长度为 256 个字符。

参数由冒号 (:) 分隔。如果省略列表中的参数,则必须指定冒号作为占位符。但是,不允许使用尾随冒号;不得以冒号结束命令或其参数列表。

可选参数列表包含在括号中,可以包含以下可选参数:

  • margin是一个整数,通过指定右边距来指定每行的字符数。
  • 协议是指定终端选项的一个或多个字母代码。
  • 终止符是终止READ操作的一个或多个字符的字符串。这些字符补充了为特定协议定义的终止字符。
  • portstate是指定 COM 端口状态的字符串。
  • baud是一个整数,指定 COM 端口的波特率。

可以将这些可选参数指定为位置参数(按所示顺序),或使用语法 /KEYWORD=value 指定为关键字参数。关键字参数可以按任意顺序指定;由于 IRIS 按从左到右的顺序执行参数,因此在某些情况下,参数之间的交互可能决定首选顺序。您可以在同一参数列表中混合位置参数和关键字参数。如果指定多个参数,则需要使用括号。

以下参数列表是等效的:

   OPEN $IO:(80:"BFU":$CHAR(13)) 
    ; all positional
   OPEN $IO:(80::$CHAR(13):/PARAMS="BFU") 
    ; mixed positional and keyword, using the /PARAMS keyword
    ; to specify a protocol letter code string.
   OPEN $IO:(/MARGIN=80:/TERMINATOR=$CHAR(13):/BREAK:/FLUSH:/UPCASE)
    ; all keyword, using separate keywords 
    ; for each protocol letter code.

在参数列表(或占位符冒号,如果未指定参数列表)后面,可以指定一个可选的超时(以秒为单位),以及一个mnespace参数来指定包含该设备的控制助记符的例程。

0
0 58
文章 姚 鑫 · 十一月 29, 2024 2m read

第三十六章 终端输入 输出 - 开关控制 $X 的转义序列更新

开关控制 $X 的转义序列更新

要选择非默认行为来更新进程的$X ,请发出%SYSTEM.Process类的 DX( n ) 方法。

系统管理员可以通过类中设置 Config.Miscellaneous 的DX属性来更改系统范围的默认行为。

在这两种情况下, n 的值都在 04 之间,如下所示:

ValueDefault Behavior for Updating $X
0Default for InterSystems IRIS
1DSM behavior
2DTM/MSM behavior

$TEST 显示定时操作结果

$TEST特殊变量由采用超时值的命令设置。这些命令包括OPENREAD$TEST的值可以设置为 10

  • 如果定时命令在超时到期之前成功,则$TEST设置为 1
  • 如果定时命令超时, $TEST将设置为 0

注:没有超时的OPENREAD命令对$TEST没有影响。

$ZA 显示读取状态

$ZA特殊变量包含许多位标志,显示当前设备上最后一次READ的状态。不能设置$ZAIRIS 控制其价值。 $ZA在下一次READ之前保持有效。 $ZA包含表中列出的值的总和,这显示了程序如何测试此变量。 ( $ZA还包含调制解调器连接状态的位标志,此处未列出。)

$ZA 读取状态值

ValueTestMeaning
1$ZA#2无论是否启用了中断,都会出现Ctrl-C
2$ZA\2#2读取超时。
256$ZA\256#2检测到无效的转义序列。
512$ZA\512#2硬件检测到奇偶校验或帧错误。

虽然$ZA显示的许多条件都是错误,但它们不会通过捕获$ZTRAP特殊变量来中断程序流程。与这些错误有关的程序必须在每次READ之后检查$ZA 。当然,启用中断的Ctrl-C将捕获到$ZTRAP

0
0 58
文章 姚 鑫 · 十一月 28, 2024 2m read

第三十五章 终端输入 输出 - 特殊变量显示 I O 条件

WRITE * and $X and $Y

WRITE *不会更改$X$Y 。因此,可以将控制序列发送到终端, $X$Y仍将反映真实的光标位置。某些控制序列确实会移动光标,因此可以在需要时直接设置$X$Y

$X$Y 示例

在以下示例中,控制序列将 VT100 终端中的光标移动到第 10 行、第 20 列,并相应地设置$X$Y

 ; set DY and DX to desired 
 ; values for $Y and $X 
 SET DY=10
 SET DX=20
 ; ...
 ; escape sequence moves
 ; cursor to desired position
 WRITE *27, *91, DY+1, *59, DX+1, *72
 ; ...
 ; updates $X and $Y
 SET $Y=DY
 SET $X=DX

转义序列对 $X$Y的影响各不相同

转义序列可以改变$X$Y值上的回显效果。三个因素控制着这种影响:

  • 操作系统,设置默认行为。
  • 是否在OPENUSE命令中指定了 /NOXY(禁用$X$Y处理)。
  • 可以使用%SYSTEM.Process类的 DX() 方法来设置$X如何处理当前进程的转义序列。可以通过类中设置 Config.MiscellaneousDX 属性来建立系统范围的默认行为。

转义序列影响 WindowsUNIX® 系统上的 $X$Y

默认情况下,在 UNIX®Windows 上,当写入或回显任何包含 ASCII 转义字符(十进制值 27)的字符串时, IRIS 会更新$X$Y,就像更新任何其他字符序列一样。因此,终端执行但不显示的 ANSI 标准控制序列可能会打乱$X和$Y与光标位置的关系。

避免此问题的最简单方法是使用DX()方法来更改行为(请参阅下一节)。或者,可以在WRITE *语句中使用字符串中每个字符的 ASCII 值。

控制序列示例

而不是使用代码:

%SYS>WRITE $CHAR(27)_"[lm"

可以使用以下不更新$X$Y 的等效语句:

%SYS>WRITE *27,*91,*49,*109
0
0 58
文章 姚 鑫 · 十一月 27, 2024 2m read

第三十四章 终端输入 输出

概述

ObjectScript 提供支持串行异步 ASCII 终端的命令。还可以将这些命令与控制台 I/O 结合使用。

使用终端 I/O,例程可以:

  • 启用或禁用传入字符的回显。
  • 发送和接收 ANSI 标准转义序列。
  • 控制键盘中断并编程特殊的用户交互,包括格式化屏幕、反向视频和用于跳过字段的特殊键。
  • 启用和禁用Ctrl-C中断的识别。
  • 通过 XON ( Ctrl-Q ) 和 XOFF ( Ctrl-S ) 控制传入和传出数据流。
  • 指定 COM 端口状态参数和调制解调器波特率。
  • 当指定自己的终止字符集时,请遵循外部协议。
  • 与非终端设备通信,例如自动化仪器。

在大多数平台上,打印机被视为终端 I/O 设备。 UNIX® 系统始终将打印机作为终端 I/O 设备来处理。在 Windows 上,通过串行通信端口连接的打印机被视为终端 I/O 设备。否则,Windows 系统将打印机作为顺序文件 I/O 设备处理。

登录终端或控制台是主要设备

登录 IRIS 的终端或控制台是主要设备。无需打开主要设备。如果尚未发出OPENUSE ,则进程第一次发出READWRITE时,系统会自动打开主设备,并将其设置为当前设备,就像您已显式发出OPEN 0 USE 0一样。

在本页的其余部分中, “终端”一词用于指代终端和控制台。

特殊变量显示 I/O 条件

I/O 命令可以影响特殊变量的值。您可以测试这些变量以确定 I/O 条件:

  • $IO包含当前设备的名称。
  • $TEST包含一个布尔值,显示最近的定时操作是否成功。
  • $X$Y显示光标的位置。
  • $ZA$ZB$KEY显示有关READ操作的信息。 $ZB$KEY相似,但不相同。

$X$Y 以及光标位置

$X包含光标或打印头的水平位置, $Y包含垂直位置。 $X=0,$Y=0表示CRT 屏幕或打印页的左上角。 IRIS 计算$X$Y256;也就是说,它们的范围是从 0255,然后又从 0 开始。

回显角色的效果

Character 特点ASCII Code ASCII 码对$X 的影响对$Y 的影响
Form Feed换页12$X=0
Return返回13$X=0
Line Feed换行10$X=$X
Backspace退格键8$X=$X-1
Tab选项卡9$X=$X+1
任何可打印的 ASCII 字符32 through 126 32 至 126$X=$X+1$Y=$Y

OPENUSES协议关闭回显。该协议还禁止在输入期间更改$X$Y ,以便它们真正指示光标的位置。

0
0 71
文章 姚 鑫 · 十一月 26, 2024 2m read

第三十三章 UDP 客户端 服务器通信 - IPv4 和 IPv6

UDP 支持 IPv4IPv6 互联网协议。由于这些协议不兼容,服务器和客户端都必须使用相同的Internet协议,否则传输将失败。

IPv4 地址具有以下格式。 n0255 范围内的十进制整数:

n.n.n.n

可以将 IPv4 协议指定为"0.0.0.0" 。

IPv6 地址具有以下完整格式。 h是一个具有四个十六进制数字的十六进制数:

h:h:h:h:h:h:h:h

通常,IPv6 地址的缩写方式是消除前导零并用双冒号 (::) 替换连续的零部分; IPv6 地址中只能使用一个双冒号。通过使用 IPv4 缩写规则,可以将 IPv6 协议指定为“::” (意味着所有 8h部分的值为 0000)。

建立互联网协议:

  • 客户端必须在 %New() 方法中建立 IPv4IPv6。默认为 IPv4
  • 这必须与GetHostAddr()方法中指定并在Send()方法中提供(以二进制形式)的 IPv4IPv6 协议匹配。

以下是 IPv4 传输:

Server
 SET sobj=##class(%Net.UDP).%New(3001,"127.0.0.1")



  SET inmsg=sobj.Recv() 
Client
 SET cobj=##class(%Net.UDP).%New()   /* the default is IPv4 */
 SET bhost=##class(%Net.UDP).GetHostAddr("127.0.0.1")
 SET outmsg="this is the message to send"
 WRITE cobj.Send(outmsg,bhost,3001) 

以下是 IPv6 传输:

Server
 SET x=##class(%SYSTEM.INetInfo).IsIPV6Enabled()
 IF x=1 {
    SET sobj=##class(%Net.UDP).%New(3001,"::1")



  SET inmsg=sobj.Recv() }
  ELSE {WRITE "IPv6 not enabled" } 
Client
 SET cobj=##class(%Net.UDP).%New(0,"::")
 SET bhost=##class(%Net.UDP).GetHostAddr("::1")
 SET outmsg="this is the message to send"
 WRITE cobj.Send(outmsg,bhost,3001) 

处理主机地址的方法可在%SYSTEM.INetInfo类文档中找到。

0
0 89
文章 姚 鑫 · 十一月 25, 2024 3m read

第三十二章 UDP 客户端 服务器通信

本页介绍如何使用 UDP 在进程之间建立远程通信。

介绍

通过%Net.UDP来支持 UDP。此类提供以下方法: Send()数据包到指定的目的地和端口、 Recv()来自套接字的数据包以及Reply()发送器最后收到的数据包。

目标被标识为本地主机名或者 IPv4IPv6 主机地址。该端口可以是指定的端口号或动态端口分配。

建立UDP套接字

要使用 UDP,必须使用%New()方法来创建 UDP 套接字对象。然后,该对象实例用于发送、接收和回复数据包传输。

创建 UDP 套接字对象时,可以指定端口号和主机地址,如下例所示:

  SET UPDOref=##class(%Net.UDP).%New(3001,"0.0.0.0")

端口号和主机地址都是可选的。 %New()方法返回 UDP 套接字对象实例的 OREF(对象引用)。

  • 服务器等待接收请求,然后提供所请求的信息。因此,传输的这一方可以称为接收方或提供方。当提供者创建 UDP 对象时,它必须定义接收请求的端口号。
  • 客户端发送信息请求,然后接收回复。因此,传输的这一方可以称为发送方或请求方。当请求者创建 UDP 对象时,它可以使用动态端口号。默认值为0。当它发送数据包时,必须指定提供者的主机名和端口号。

主机地址

Send()方法指定目标的二进制地址。这是主机地址的二进制版本。必须使用GetHostAddr()方法创建此二进制主机地址,如下所示:

  SET client=##class(%Net.UDP).%New()
  SET addrbin=##class(%Net.UDP).GetHostAddr("172.16.61.196")
  WRITE client.Send("message text",addrbin,3001)

以向GetHostAddr()指定主机名、IPv4 地址或 IPv6 地址,如以下示例所示:

  SET hostname="MYLAPTOP"
  SET IPv4="172.16.61.196"
  SET IPv6="::1"
  SET flag=$SYSTEM.INetInfo.CheckAddressExist(hostname)
  IF flag=1 { SET addrbin=##class(%Net.UDP).GetHostAddr(hostname)
              WRITE "host name valid",! }
     ELSE { WRITE "not a hostname: ",hostname,! }
  SET flag=$SYSTEM.INetInfo.CheckAddressExist(IPv4)
  IF flag=1 { SET addrbin=##class(%Net.UDP).GetHostAddr(IPv4)
              WRITE "IPv4 valid",! }
     ELSE { WRITE "not an IPv4 address: ",IPv4,! }
  SET flag=$SYSTEM.INetInfo.CheckAddressExist(IPv6)
  IF flag=1 { SET addrbin=##class(%Net.UDP).GetHostAddr(IPv6)
              WRITE "IPv6 valid",! }
     ELSE { WRITE "not an IPv6 address: ",IPv6,! }

可以使用AddrToHostName()方法将此二进制主机地址扩展回主机名,如以下示例所示:

  SET addrbin=##class(%Net.UDP).GetHostAddr("MYLAPTOP")
  WRITE $SYSTEM.INetInfo.AddrToHostName(addrbin)

可以使用LocalHostName()法来确定主机名。可以使用HostNameToAddr()方法将主机名转换为 IPv4IPv6 地址,如以下示例所示:

  SET localhost=$SYSTEM.INetInfo.LocalHostName()            /* get host name */
     WRITE "local host name is ",localhost,!
  SET addrbin=##class(%Net.UDP).GetHostAddr(localhost)      /* compress to binary address */
     WRITE "binary form of IP address is ",addrbin,!
  SET hostname=$SYSTEM.INetInfo.AddrToHostName(addrbin)     /* expand binary address to host name */
     WRITE "binary IP address expands to ",hostname,!
  SET ipaddr=$SYSTEM.INetInfo.HostNameToAddr(hostname)      /* host name to IP address */
     WRITE "hostname corresponds to IP address ",ipaddr,!
0
0 73
文章 姚 鑫 · 十一月 24, 2024 5m read

第三十一章 TCP 高级主题

本页讨论使用 TCP/IPIRIS 数据平台进程之间进行通信的几个高级主题。

连接管理

服务器一次仅维护一个连接。如果在另一个连接打开时第二个客户端尝试连接,TCP/IP 会将该客户端放入队列中。在队列中时,第二个客户端可以向端口写入数据,就像已连接一样。第二个客户端写入的数据保留在缓冲区中,直到第一个连接关闭并且第二个客户端连接为止。

如果第二个客户端在连接存在之前发出READ,则会挂起。当第二个客户端在队列中时,第三个客户端的任何连接尝试都会失败。

如果已经打开 TCP 设备的客户端在第一个连接仍然存在时尝试第二次连接,则第二个OPEN命令会导致错误。将这种情况视为错误而不是USE命令可以防止出现意外的结果。如果错误的程序认为它已打开新连接,而实际上它正在重用可能具有不同目标或不同参数的现有连接,则可能会出现此类意外结果。

TCP 设备的作业命令

可以使用JOB命令来实现TCP并发服务器。 TCP 并发服务器允许同时为多个客户端提供服务。在这种模式下,客户端不必等待服务器完成为其他客户端提供服务。相反,每次客户端请求服务器时,它都会为该客户端生成一个单独的子作业,只要客户端需要它,该子作业就会保持打开状态。一旦生成该子作业(由JOB命令的返回指示),另一个客户端就可以请求服务,并且服务器也将为该客户端创建一个子作业。

非并发和并发模式下的客户端/服务器连接。

并发服务器使用JOB命令并设置了切换并发服务器位(位 4 或位 16)。位 16 是推荐设置。

  • 如果设置了位 4,则JOB命令将主要输入和主要输出进程参数中的 TCP 设备传递给衍生进程。每当在switch中包含位 4 时,必须在主要输入和主要输出过程参数中指定 TCP 设备。主输入和主输出必须使用相同的设备。不建议使用位 4;有关详细信息,请参阅《ObjectScript 参考》中的JOB命令。
  • 如果设置了位 16,则JOB命令将 TCP 设备、主要输入和主要输出进程参数的三个独立设备传递给生成的进程。可以使用主体输入和主体输出进程参数在JOB命令中指定其中两个 TCP 设备。还可以默认这些参数,如以下示例所示: JOBchild:(:16:input:output)JOB child:(:16::))

在发出JOB命令之前,为主要输入和主要输出指定的设备必须:

  • 保持开放
  • 监听 TCP 端口
  • 已接受传入连接

在执行JOB命令之后,生成过程中的设备仍在侦听 TCP 端口,但不再具有活动连接。应用程序应在发出JOB命令后检查$ZA ,以确保 TCP 设备状态中的 CONNECTED 位已重置。

生成的进程使用指定的 TCP 设备在指定的入口点启动。TCP 设备在子进程中与在父进程中具有相同的名称。 TCP 设备有一个连接的套接字。继承的TCP设备处于S(流)模式。但是,子进程可以使用USE命令更改模式。我们建议服务器以A(接受)模式打开TCP 设备。

  • switch =4 时,如果主设备上发生错误,作业只是停止,而不采取错误陷阱。这是因为当switch =4 时,TCP 设备是主要设备。要支持错误捕获,请使用switch =16 并为 TCP 设备指定另一个设备。
  • switch =4 时,如果远程 TCP 设备关闭连接,作业就会停止,而不会出现错误陷阱。要覆盖此默认行为并生成错误,必须设置%SYSTEM.Process类的 DisconnectErr() 方法。

可以使用%SYSTEM.Socket类方法(而不是JOB命令)来创建并发 TCP 服务器连接。但是,请注意, %SYSTEM.Socket方法假定辅助作业已启动。如果不需要侦听器作业来启动辅助作业,并且侦听器作业知道辅助作业的进程 ID (PID),则可以使用这些方法进行并发 TCP 服务器连接。

在某些情况下,TCP 将单独的记录连接起来形成单个记录。如果客户端或服务器进程向 TCP 端口发出一系列由 WRITE 分隔的WRITE命令,则可能会发生串联WRITE #命令来刷新缓冲区,无论连接的另一端是否正在等待READ命令。

下面的第一个示例概述了进程 A 在进程 B 将两条记录写入 TCP 端口时等待READ命令时如何接收两条单独的记录。

Process A                            Process B
%SYS> USE "|TCP|41880" R A U 0 W A   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
<RETURN>                             <RETURN>
ONE
%SYS> USE 41880 R A U 0 W A 
<RETURN>
TWO

第二个示例概述了进程 A 在进程 B 完成向 TCP 端口写入两条记录后发出READ命令时如何接收一条串联记录。

Process A                           Process B
.                                   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
.                                   <RETURN>
ONE
%SYS> USE "/TCP/41880" R A U 0 W A 
<RETURN>
ONETWO

多路复用 IRIS TCP 设备

%SYSTEM.Socket在提供了多路复用 IRIS TCP 设备的方法。 Fork()Select()方法允许使用单个作业同时处理接受新连接和从连接的 TCP 设备读取数据。监听的 TCP 设备收到连接后,使用Fork()创建新的 TCP 设备用于读取数据。原始侦听 TCP 设备继续接受传入连接。可以使用Select()方法来等待侦听和连接的 TCP 设备。当新连接到达或数据可用时, Select()返回收到信号的设备名称。

可以使用Select()、 Publish()、 Export()Import()方法来让侦听器作业接受传入连接并将连接的设备传递给工作人员作业。该工作人员作业可以与远程客户端进行通信。

0
0 66
文章 姚 鑫 · 十一月 23, 2024 2m read

第三十章 TCP 客户端 服务器通信 - 作业服务器资源

作业服务器资源

如果正在编写一个IRIS服务器来与无法控制的客户端连接,则服务器进程必须发出CLOSE命令来关闭TCP连接。就 IRIS而言,CLOSE命令确实会关闭连接,但是在内部TCP/IP会在服务器上为这个连接保留最长两分钟的资源。

jobserver用于为TCP/IP作业提供服务时,可能会产生意想不到的结果。当一个JOBSERVER进程执行暂停时,该进程立即返回到可用的JOBSERVER进程池,但其资源在内部保留最多两分钟。由于JOBSERVER进程是在第一个可用的基础上分配的,因此来自数量相对较少的客户机的重载可能会耗尽JOBSERVER进程的资源。

为了避免这个问题,在JOBSERVER下运行的JOB打开的TCP/IP服务器应该显式地发出一个CLOSE命令,然后在最后的QUITHALT)命令之前发出一个简短的HANG命令。根据TCP/IP规范,需要一个HANG120来保证在JOBSERVER的转世之间没有资源仍在使用。在实践中,一秒的HANG通常足以在JOBSERVER进程之间均匀地分配资源负载。

自动切断

TCP绑定连接在以下条件下自动关闭:

  • IRIS致命错误

  • 客户端或服务器进程的RESJOB

  • iris stop

  • iris force

断开连接的影响

断开连接对保留在输出缓冲区中的数据的影响由OPENUSE期间建立的/CLOSEFLUSH设置决定。默认是刷新数据。

如果一方关闭连接,但另一方发出新的WRITE命令,则第一个WRITE命令可能成功。任何附加的WRITE命令都会收到<WRITE>错误。

从客户端,所有发送到关闭连接端的READ命令都收到<READ>错误。必须关闭设备并重新打开,以重新与服务器建立通信。

在服务器端,<READ><WRITE>错误后的第一个READ等待并接受一个新的连接。

可以使用%SYSTEM.TCPDevice.GetDisconnectCode()在方法中以返回导致当前TCP设备上<READ><WRITE>错误的内部错误。$IO必须是TCP设备。

相关类

%SYSTEM.INetInfo%SYSTEM.TCPDevice%SYSTEM.Socket%IO.Socket

0
0 50
文章 姚 鑫 · 十一月 22, 2024 2m read

第二十九章 TCP 客户端 服务器通信 - 记录的拼接

记录的拼接

在某些情况下,TCP会将不同的记录连接在一起形成单个记录。如果客户端或服务器进程向一个由WRITE分隔的TCP端口发出一系列WRITE命令,则可能会发生串接!或用于刷新缓冲区的WRITE#命令,而不管读命令是否在连接的另一端等待。

Process A                            Process B
%SYS> USE "|TCP|41880" R A U 0 W A   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
<RETURN>                             <RETURN>
ONE
%SYS> USE 41880 R A U 0 W A 
<RETURN>
TWO

第二个例子概述了在进程B完成将两条记录写入到TCP端口之后,当它发出读命令时,进程A如何接收一条串联的记录。

Process A                           Process B
.                                   %SYS> USE "|TCP|41880" WRITE "ONE",!,"TWO"
.                                   <RETURN>
ONE
%SYS> USE "/TCP/41880" R A U 0 W A 
<RETURN>
ONETWO

多路复用 TCP设备

类中的%SYSTEM.Socket提供了多路传输 TCP设备的方法。Fork()Select()方法允许让单个作业同时处理接受新连接和从连接的TCP设备读取数据。侦听的TCP设备收到连接后,在中使用Fork()打开以创建用于读取数据的新的TCP设备。原始侦听的TCP设备继续接受传入的连接。可以使用在的Select()来等待侦听和连接的TCP设备。当新连接到达或数据可用时,Select()将返回发出信号的设备名称。

可以使用Select()Publish()Export()Import()方法,使侦听器作业接受传入连接并将连接的设备传递给工作作业。此工作作业可以与远程客户端通信。

正在关闭连接

客户端或服务器端都可以结束TCP绑定连接。关闭连接的首选方法是客户端向TCP设备发出close命令。(或者,客户端可以发出HALT命令。)然后服务器应该向该设备发出另一个READ命令,并接收到<READ>错误,然后为TCP设备发出一个CLOSE命令。

这种顺序的原因是,根据TCP/IP标准,连接资源在CLOSE后保持两分钟,但仅用于“主动关闭器”——首先执行CLOSE的进程。因此,最好先关闭客户机,因为服务器的资源通常比客户机的资源更有限。

使用CLOSE命令断开连接

从客户端或服务器发出这样的CLOSE命令:

CLOSE "|TCP|devicenum"

如上所述,客户端最好先发出CLOSE命令。如果服务器首先发出CLOSE命令,客户端将收到<WRITE>错误,然后应该发出CLOSE命令。

0
0 66
文章 姚 鑫 · 十一月 21, 2024 2m read

第二十八章 TCP 客户端 服务器通信 - JOB命令示例

JOB命令示例

以下示例显示了一个非常简单的并发服务器,只要它检测到来自客户端的连接,就会产生一个子作业。 JOB指定一个并发服务器位开关值(值16)并通过符号表(值1):16+1=17

server
  SET io="|TCP|1" 
  SET ^serverport=7001 
  OPEN io:(:^serverport:"MA"):200 
  IF ('$TEST) { 
       WRITE !,"Cannot open server port" 
       QUIT }
  ELSE { WRITE !,"Server port opened" }
loop
     USE io READ x ; Read for accept 
     USE 0 WRITE !,"Accepted connection" 
     JOB child:(:17:io:io) ;Concurrent server bit is on 
     GOTO loop
child
  WRITE $JOB,! ; Send job id on TCP device to be read by client 
  QUIT
client
  SET io="|TCP|2" 
  SET host="127.0.0.1" 
  OPEN io:(host:^serverport:"M"):200 ;Connect to server
   IF ('$TEST) { 
       WRITE !,"cannot open connection" Quit }
   ELSE { 
       WRITE !,"Client connection opened" 
       USE io READ x#3:200 ;Reads from subjob 
       }
   IF ('$TEST) { 
       WRITE !,"No message from child" 
       CLOSE io 
       QUIT }
   ELSE {
       USE 0 WRITE !,"Child is on job ",x 
       CLOSE io 
       QUIT }

子进程使用继承的TCP连接将其作业ID(在本例中假设为3个字符)传递回客户机,之后子进程退出。客户端打开与服务器的连接,并在打开的连接上读取子任务的作业ID。在本例中,变量主机的IPv4格式值“127.0.0.1”表示到本地主机的环回连接。如果host设置为服务器的IP地址或名称,则可以在与服务器不同的机器上设置客户端。

原则上,子服务器和客户端可以进行扩展通信,多个客户端可以同时与服务器的各自子服务器进行通信。

请注意,这个简单的示例不包含用于检测和处理断开或读取操作失败的逻辑。

0
0 82
文章 姚 鑫 · 十一月 20, 2024 3m read

第二十七章 TCP 客户端 服务器通信 - 连接管理

连接管理

服务器一次只维护一个连接。如果第二个客户端在另一个连接打开时尝试连接,则 TCP/IP 将该客户端放入队列中。在队列中时,第二个客户端可以像已连接一样写入端口。第二个客户端写入的数据保留在缓冲区中,直到第一个连接关闭并且第二个客户端连接。

如果第二个客户端在连接存在之前发出 READ,它就会挂起。当第二个客户端在队列中时,第三个客户端的任何连接尝试都会失败。

如果已经打开 TCP 设备的客户端在第一个连接仍然存在时尝试第二次连接,则第二个 OPEN 命令会导致<COMMAND> 错误。将这种情况视为错误而不是 USE 命令可以防止出现意外结果。如果一个错误的程序认为它打开了一个新连接,而实际上它正在重用一个可能具有不同目标或不同参数的现有连接,则可能会出现这种意想不到的结果。

TCP 设备的作业命令

可以使用 JOB 命令来实现 TCP 并发服务器。 TCP 并发服务器允许同时为多个客户端提供服务。在这种模式下,客户端不必等待服务器完成对其他客户端的服务。相反,每次客户端请求服务器时,它都会为该客户端生成一个单独的子作业,只要客户端需要它,该子作业就会保持打开状态。一旦生成此子作业(由 JOB 命令的返回指示),另一个客户端可能会请求服务,服务器也会为该客户端创建一个子作业。

非并发和并发模式下的客户端/服务器连接。

并发服务器使用设置了切换并发服务器位(第 4 位或第 16 位)的 JOB 命令。位 16 是推荐设置。

如果设置了第 4 位,则 JOB 命令将主要输入和主要输出进程参数中的 TCP 设备传递给派生进程。无论何时在开关中包含位 4,都必须在主要输入和主要输出过程参数中指定 TCP 设备。必须对主要输入和主要输出使用相同的设备。不推荐使用位 4

如果设置了第 16 位,则 JOB 命令将 TCP 设备的三个独立设备、主要输入和主要输出过程参数传递给派生进程。使用主要输入和主要输出过程参数在 JOB 命令中指定其中两个 TCP 设备。还可以默认这些参数,如以下示例所示:JOB child:(:16:input:output)JOB child:(:16::))

在发出 JOB 命令之前,为主要输入和主要输出指定的设备必须:

  • 保持开放
  • 监听 TCP 端口
  • 已接受传入连接

JOB 命令之后,生成过程中的设备仍在TCP 端口上侦听,但不再有活动连接。应用程序应在发出 JOB 命令后检查 $ZA 以确保 TCP 设备状态中的 CONNECTED 位已重置。

派生的进程使用指定的 TCP 设备在指定的入口点开始。 TCP 设备在子进程中的名称与在父进程中的名称相同。 TCP 设备有一个连接的套接字。继承的 TCP 设备处于 S(流)模式。但是,子进程可以使用 USE 命令更改模式。我们建议服务器以 A(接受)模式打开 TCP 设备。

派生进程中的 TCP 设备处于连接状态:与设备从客户端打开后接收到的状态相同。生成的进程可以使用带有 USE 0USE $PTCP 设备。它还可以隐式使用 TCP 设备(如果 switch=4)。但是,出于以下原因,switch=16 优于 switch=4

  • switch=4 时,如果在主设备上发生 <READ> 错误,则作业会简单地停止,而不会出现错误陷阱。这是因为当 switch=4 时,TCP 设备是主要设备。要支持错误捕获,请使用 switch=16并为 TCP 设备指定另一个设备。
  • switch=4 时,如果远程 TCP 设备关闭连接,作业会简单地停止,而不会出现错误陷阱。要覆盖此默认行为并生成 <DSCON> 错误,必须在类中设置 %SYSTEM.ProcessDisconnectErr()方法。

可以在类方法中使用 %SYSTEM.Socket而不是 JOB 命令来创建并发 TCP 服务器连接。但是,请注意方法中的 %SYSTEM.Socket 假定工作作业已经启动。如果不需要侦听器作业来启动辅助作业,并且侦听器作业知道辅助作业的进程 ID (PID),则可以将这些方法用于并发 `TCP 服务器连接。

0
0 103
文章 姚 鑫 · 十一月 19, 2024 2m read

第二十六章 TCP 客户端 服务器通信 - $ZB 和 READ 命令

$ZBREAD 命令

$ZB 保存终止读取的字符。该字符可以是以下之一:

  • 终止字符,例如回车
  • 固定长度 READ x#y 的第 y 个字符
  • READ *X 的单个字符
  • 定时读取过期后的空字符串
  • 转义序列
  • 请注意,如果一个字符串以 CR LF 结尾,则只有 CR 会放在 $ZB 中。

TCP 设备的 WRITE 命令

在使用 OPENUSE 建立连接后,WRITE 命令将数据从客户端或服务器发送到 TCP 设备。

语法如下:

WRITE x
WRITE ! 
WRITE #

WRITE如何工作

WRITE x 在建立连接后将 x 从客户端或服务器发送到缓冲区。

WRITE !WRITE # 不表示换行和换页。相反,它们告诉 IRIS 刷新缓冲区中保留的所有字符,并通过网络将它们发送到目标系统。

可以使用 %SYSTEM.INetInfo类的 TCPStats() 方法确定当前 TCP 连接执行的写入次数。

WRITE 修改 $X$Y

IRIS 将缓冲区中的字符数存储在 $X 特殊变量中。

ASCII 字符 <return><line feed> 不包括在此计数中,因为它们不被视为记录的一部分。用 WRITE 刷新缓冲区!将 $X 重置为 0,并将 $Y 的值增加 1。使用 WRITE # 刷新缓冲区将 ASCII 字符 <form feed> 作为单独的记录写入,并将 $Y 重置为 0

WRITE命令错误

在以下任何情况下,都可能收到 <WRITE> 错误。

  • 如果超过最大字符串大小(1024 个字符)而不刷新缓冲区。
  • 如果在其中没有字符时刷新写入缓冲区(TCP/IP 忽略长度为 0 的记录)。
  • 如果在服务器收到来自客户端的连接请求之前从服务器向客户端发送 WRITE 命令。 ( IRIS 在服务器上产生 <WRITE> 错误。)

WRITE控制命令

TCP 绑定设备支持一系列具有 WRITE *-n 语法的控制命令。

  • WRITE *-2 - 在当前连接到客户端的服务器模式会话上,此命令会断开与会话的连接。要接受新会话,可以在设备上执行新的 READ 命令。
  • WRITE *-3 - 将任何缓冲的输出发送出 TCP 连接;即,对输出缓冲区中的数据执行 TCP SEND 操作。如果数据是压缩(/GZIP)流数据,*-3 发送数据时不标记压缩端点。将 $X 重置为 0。将 $Y 加 1。如果没有缓冲输出,则此命令不执行任何操作。
  • WRITE *-99 - 发送压缩 (/GZIP) 流数据。首先用压缩端点标记输出缓冲区中的数据,然后通过对输出缓冲区数据执行 TCP SEND 操作来发送此压缩流数据。
0
0 88
文章 姚 鑫 · 十一月 17, 2024 3m read

第二十四章 TCP 客户端 服务器通信 - 当前 TCP 设备

当前 TCP 设备

可以使用 %SYSTEM.TCPDevice方法返回当前 TCP 设备的 IP 地址和端口号。可以使用 Help() 方法列出这些方法,如下所示:

  DO $SYSTEM.TCPDevice.Help()

可以通过在 Help() 中指定方法名称来显示有关特定方法的信息,如以下示例所示:

  DO $SYSTEM.TCPDevice.Help("LocalAddr")
IMP>DO $SYSTEM.TCPDevice.Help("LocalAddr")
method:class的描述 LocalAddr:%SYSTEM.TCPDevice
 
LocalAddr(Format:%Integer=0)
Get local IP address of current TCP device.<br>
<br>
<b>Parameters:</b> <br>
<b>Format</b> - The format of address to be returned. If this argument is omitted the default value is 0. The value could be:<br>
<ul><li>0: in text format,  'dotted' decimal string for IPV4, colon-hex address string for IPV6.</li>
<li>1: in binary format, 4 character length for IPV4, 16 characters for IPV6.</li></ul>
<b>Return:</b> <br>
Returns the local IP address associated with the TCP device. It could be in binary or text format depends on the <b>Format</b> parameter.
For binary format the IP address is in Network order.<br>
If the current device ($IO) is not a TCP device, it gets <FUNCTION> error.<br>
If the TCP device is in 'listening' state, the IP address would be all zeros (INADDR_ANY).<br>
 

TCP 设备的 USE 命令

从客户端或服务器发出的 USE 命令使可以准备使用之前打开的 TCP 连接发送或接收数据。它具有以下语法(必须指定冒号,如图所示):

USE devicename:(::mode:terminators)
  • devicename - |TCP| 形式的字符串后跟一些数字。设备名称的数字部分称为设备标识符。如果在 OPEN 参数中未指定端口号,则此设备标识符必须是唯一的五位 TCP 端口号。如果在 OPEN 参数中指定了端口号(这是首选做法),则该设备标识符可以是任何唯一的数字,只要单个作业使用的所有 TCP 设备名称都是不同的。
  • mode - 可选——USE 支持与 OPEN 相同的模式参数。请参阅“TCP 设备的 OPENUSE 命令关键字”。
  • terminators - 可选 — 最多八个用户终止字符的列表,这些字符将终止 TCP 绑定设备上的读取。同时指定 T 模式和用户终止符是没有意义的,但如果这样做,T 模式将被忽略。

最简单的 USE 形式从 OPEN 命令中获取其模式和终止符参数,如以下示例所示:

   USE "|TCP|4"

可以在设备打开后替换、添加或删除模式参数和用户终止符。

要替换 OPEN 中指定的参数,请在 USE 中指定替换值。在以下示例中,USE 命令将 OPEN 模式替换为 PSTE 模式并关闭所有用户终止符:

   USE "|TCP|4":(::"PSTE")

增加或删除OPEN中指定的模式参数,用“+”号引入将要开启的模式参数,“-”号引入将要关闭的模式参数。如果不指定“+”或“-”,则新的模式参数集将替换现有模式参数。在以下示例中,USE 命令关闭 Q 模式(立即发送)并打开 W 模式(等待)。它使模式字符串的其余部分保持不变:

   USE "|TCP|4":(::"-Q+W")

在以下示例中,USE 命令保留模式字符串不变并指定一组新的用户终止符。

   USE "|TCP|4":(::"+":$CHAR(3,4))
0
0 57
文章 姚 鑫 · 十一月 15, 2024 7m read

第二十二章 TCP 客户端 服务器通信 - TCP设备的OPEN和USE命令关键字

TCP设备的OPENUSE命令关键字

可以使用位置参数(如上所述)或关键字参数。下表描述了使用OPENUSE命令控制TCP设备的关键字。还有其他只能在OPEN命令中指定的OPEN-only关键字(本章稍后将描述)。所有关键字参数都是可选的。

TCP设备的OPENUSE命令关键字

KeywordDefaultDescription
/ABSTIMEOUT[=1]0指定读超时行为。确定TCP在接收到数据时是否应重新初始化超时时间。如果/ABSTIMEOUT=0(默认值),则每次接收数据时timeout都会重置为原始值。如果/ABSTIMEOUT/ABSTIMEOUT=1,则在接收数据时超时时间继续倒数。
/ACCEPT[=n] or /ACC[=n]0对应于“A”模式参数字符,该参数指定一旦接受来自客户端作业的连接,服务器上的初始读取就以零长度字符串终止。/ACCEPT/ACCEPT=n对于n的非零值启用A模式。/ACCEPT=n表示零值n禁用a模式。
/CLOSEFLUSH[=n]1指定当设备关闭时,对保留在输出缓冲区中的数据的处理。/CLOSEFLUSH/CLOSEFLUSH=n对于n的非零值将刷新剩余数据。/CLOSEFLUSH=n表示n为零时丢弃剩余数据。
/COMPRESS=str""指定流数据压缩类型。可以启用压缩类型为ZLIBZSTD。可以指定/COMPRESS=""来禁用压缩。/COMPRESS="zlib"等价于/GZIP=1。要压缩字符串,使用%SYSTEM.Util.Compress()
/CRLF[=n]0对应于“C”模式参数字符,它修改输入和输出时回车的处理。/CRLF/CRLF=nn的非零值启用C模式。/CRLF=n对于零值n禁用C模式。
/ESCAPE[=n]or/ESC[=n]0对应于“E”模式参数字符,它指定输入流中的转义序列被解析并放入$ZB中。/ESCAPE/ESCAPE=n对于n的非零值启用E模式。/ESCAPE=n对于零值n禁用E模式。
/GZIP[=n]1指定兼容gzip的流数据压缩。/GZIP/GZIP=n(对于n的非零值)在WRITE时进行压缩,在READ时进行解压缩。/GZIP=0禁用压缩和解压。在发出/GZIP=0来禁用压缩和解压之前,检查$ZEOS特殊变量以确保流数据读取没有进行。/GZIP压缩对I/O转换没有影响,例如使用/IOTABLE建立的转换。这是因为压缩是在所有其他转换(加密除外)之后应用的,而解压是在所有其他转换(加密除外)之前应用的。
/IOTABLE[=name]or/IOT[=name]如果不指定name,则使用设备默认的I/O转换表。为设备建立I/O转换表。
/KEEPALIVE=n系统默认值(仅适用于WindowsAIXLinux)为设备设置不同于系统默认值的保活定时器。一个整数,指定TCP连接保持活跃的秒数。与位置参数keepalivetime相同。有效值为30 ~ 432000。(432000秒等于5天。)小于30的值默认为30。如果省略或设置为0,则使用系统默认值。可以使用/NOKEEPALIVE禁用此设置;一旦禁用,它就不能重新启用,直到这个TCP设备被关闭。
/NODELAY=n1指定数据包是捆绑发送还是单独发送。如果/NODELAY=1(缺省值),则立即发送每个数据包。如果/NODELAY=0, TCP驱动程序使用优化算法将包捆绑在一起。这可能会对单个数据包造成轻微的传输延迟,但通过减少网络流量,可以提高整体性能。/NODELAY没有对应的模式参数字符。/NODELAY的使用应该与/SENDIMMEDIATE的使用协调。
/NOKEEPALIVE如果指定该参数,则在此设备上禁用系统级TCPkeepalive定时器。 IRIS在打开任何TCP设备时默认启用此定时器;在OPENUSE上发出/NOKEEPALIVE选项会覆盖这个默认值。如果/KEEPALIVE已被用于设置非默认的KEEPALIVE定时器,/NOKEEPALIVE将禁用该KEEPALIVE定时器。一旦禁用了keepalive定时器,就没有办法重新启用它,直到TCP设备关闭。看到/ KEEPALIVE
/NOXY[=n]0禁止$X$Y处理:/NOXY/NOXY=n(对于n的非零值)禁用$X$Y处理。当设备$X/$Y未被使用时,该选项可以提高性能,例如CSP。它可以极大地提高READWRITE操作的性能。此选项是超级服务器工作作业的默认设置。当/NOXY=1时,$X$Y变量的值是不确定的,保证金处理(取决于$X)被禁用。/NOXY=0启用$X$Y处理;这是默认值。/TCPNOXY/NOXY的同义词。
/OBCOUNT=n16用于/ZEROCOPY的输出缓冲区数量。输出缓冲区的默认数量是16。输出缓冲区的最小数量是2,最大数量是128n的值必须是2的幂;如果指定了非2的幂值,则将其四舍五入为2的幂。
/PAD[=n]0对应于" P "模式参数字符,该参数指定当WRITE !(LF结束符)或writ# (FF结束符)被执行。/PAD/PAD=n为n的非零值启用P模式。/PAD=n对于零值n禁用P模式。
/PARAMS=str or /PAR=str没有默认对应于模式位置参数。(它提供了一种以位置无关的方式指定模式字符串的方法。)
/POLL[=n] or /POLLDISCON[=n]对应于“D”模式参数字符,它指定断开连接的异步监视。/POLL/POLL=1对应+D/POLL=0对应-D
/PSTE[=n]0对应于“M”模式参数字符,这是指定P、S、T和E模式参数字符的一种简便方法。/PSTE/PSTE=n的非零值n启用P, S, T和E模式。/PSTE=n对于零值n禁用这些模式。
/SENDIMMEDIATE[=n] or /SEN[=n]0对应于“Q”模式参数字符,它指定发送立即模式。
`/SSL="cfg[pw] [DNShost]" or /TLS="cfg[
/STREAM[=n] or /STR[=n]0对应于“S”模式参数字符,它指定了一种不保留 TCP 消息边界的处理数据的流模式。 /STREAM/STREAM=n 对于 n 的非零值启用 S 模式。 /STREAM=n 对于 n 的零值禁用 S 模式。
/TCPNOXY已弃用。 /NOXY 的同义词。
/TCPRCVBUF=n默认接收缓冲区大小设置接收队列缓冲区大小,以字节为单位。可用于从默认值增加缓冲区大小以支持 TCP 协议大窗口。大窗口提高了具有长延迟或非常高带宽的链路的性能。有关适当的值,请参阅您的操作系统/硬件文档。
/TCPSNDBUF=n默认发送缓冲区大小设置发送队列缓冲区大小,以字节为单位。可用于从默认值增加缓冲区大小以支持 TCP 协议大窗口。大窗口提高了具有长延迟或非常高带宽的链路的性能。
/TERMINATOR=str or /TER=str无默认对应于 terminators 位置参数,它建立用户定义的终止符。
/TMODE[=n] or /TMO[=n]0对应“T”模式参数字符,指定CR、LF、FF为标准读终止符。 /TMODE/TMODE=n 对于 n 的非零值启用 T 模式。 /TMODE=n 对于 n 的零值禁用 T 模式。
/TRANSLATE[=n] or /TRA[=n]1/TRANSLATE/TRANSLATE=n 对于 n 的非零值启用设备的 I/O 转换。 /TRANSLATE=n 对于 n 的零值禁用设备的 I/O 转换。
/WAIT[=n]0对应于“W”模式参数字符,这会导致输出缓冲区不被 WRITE 刷新!和 WRITE # 命令。相反,刷新会等到下一个 WRITE *-3 命令。 /WAIT/WAIT=n 对于 n 的非零值启用 W 模式。 /WAIT=n 对于 n 的零值禁用 W 模式。
/WRITETIMEOUT[=n]1TCP写操作建立超时时间(以秒为单位)。如果写操作没有在n秒内完成, IRIS将发出<TCPWRITE>错误。如果发出<TCPWRITE>错误,应用程序应该立即关闭TCP设备以防止数据丢失。在<TCPWRITE>错误后, IRIS将不会尝试TCP写操作。最小n值与系统相关。如果n小于该平台的最小超时值, IRIS将使用该平台的最小超时值。n不能小于2。默认值(-1)表示不强制执行超时。
/XYTABLE[=name] or /XYT[=name]如果不指定name,则使用设备默认的$X/$Y动作表。为设备建立一个$X/$Y操作表。
/ZEROCOPY[=bool]0如果指定了/ZEROCOPY/ZEROCOPY=1,则开启该TCP设备的ZEROCOPY特性。ZEROCOPY支持TCP设备的多个输出缓冲区,以便在send()上利用MSG_ZEROCOPY;TCP设备不能重用输出缓冲区,直到缓冲区被TCP堆栈的通知确认。使用/OBCOUNT关键字为TCP设备设置输出缓冲区的数量。如果指定/ZEROCOPY=0,则关闭此TCP设备的ZEROCOPY特性。Linux 4.15及以上版本支持MSG_ZEROCOPY。如果操作系统不支持MSG_ZEROCOPY,则TCP设备的ZEROCOPY始终处于关闭状态。
0
0 101
文章 姚 鑫 · 十一月 14, 2024 2m read

第二十一章 TCP 客户端 服务器通信 - 客户端OPEN命令

客户端OPEN命令

客户端OPEN命令与服务器端OPEN命令只有一个方面的不同:第一个设备参数必须指定要连接的主机。要指定主机,需要包括客户端识别为主机的名称或Internet地址。

一旦建立连接,OPEN开就会成功。此时,可以读取或写入该TCP设备。但是,如果连接的服务器端是另一个 IRIS进程,则在使用WRITE命令将一些数据从客户端发送到服务器之前,服务器不会完成其连接端。因此,必须在发出任何读取命令之前发出写入命令。

客户端 OPEN 命令的一些示例是:

   OPEN "|TCP|4":("hal":4200::$CHAR(3,4)):10

此命令在端口 4200 上打开到主机 hal 的连接。它没有指定模式字符串。它指定了两个终止符(ASCII $CHAR(3)$CHAR(4)),以及默认的输入和输出缓冲区大小。它指定 10 秒的超时。

以下命令与上一个命令相同,只是目标是 IPv4 格式的显式 IP 地址。

   OPEN "|TCP|4":("129.200.3.4":4200::$CHAR(3,4)):10

可以使用 OPEN 关键字 /USEIPV6 来指定要使用的协议。

下面的命令连接到远程主机“larry”上的时间服务器,并在主输入设备上以ASCII格式打印远程主机的时间。它使用服务名daytime,本地系统将其解析为端口号:

   OPEN "|TCP|4":("larry":"daytime":"M")
   USE "|TCP|4" 
   READ x
   USE 0
   WRITE x

以下命令将 x 设置为“hello”:

   OPEN "|TCP|4":("larry":"echo":"M")
   USE "|TCP|4"
   WRITE "hello",!
   READ x

以下open命开到 Internet 地址 128.41.0.73、端口号 22101 的连接,超时为 30 秒。

   OPEN "|TCP|22101":"128.41.0.73":30
0
0 89
文章 姚 鑫 · 十一月 13, 2024 3m read

第二十章 TCP 客户端 服务器通信 - 立即发送模式(Q 模式)

立即发送模式(Q 模式)

在立即发送模式下,每个 WRITE 命令都作为其自己的数据包输出。如果不使用立即发送模式,则必须包括终止符或发出命令 WRITE *–3 以输出数据包。

通过指定“Q”模式字符或/SENDIMMEDIATE(或/SEN)关键字参数进入此模式。要关闭此选项,请指定以下任一选项:

   USE TCPDEVICE:(/SEN=0)
   USE TCPDEVICE:(::"-Q")

要重新打开此选项,请指定以下任一选项:

   USE TCPDEVICE:(/SEN=1)
   USE TCPDEVICE:(::"+Q")

立即发送模式与/NODELAY模式结合使用,前者在每次写入时创建一个包,后者在创建每个包时立即发送。当这两个选项都启用时,单个数据突发的传输速度将最大化。当每个数据单元的及时传送至关重要时,例如在传输鼠标移动时,这是有用的。当两者都关闭时,一个数据包可能包含多个写入,一个传输可能包含多个数据包。这减少了网络流量并提高了整体性能。立即发送模式的默认设置为关闭。/NODELAY模式的默认设置为打开。

流模式(S模式)

在流模式下, IRIS不会保留数据流中的TCP消息边界。发送时,如果数据不适合消息缓冲区, IRIS会在将数据放入缓冲区之前刷新缓冲区。

接收时,可以接收最大字符串长度的数据。所有读取都等待达到终止符或缓冲区变满的完全超时。当禁用此模式(默认)时,处于数据包模式。

继承 TCP 设备的 Jobbed 进程自动设置为 Stream 格式。可以使用 USE 命令重置格式。

缓冲区大小

TCP 设备的 ibufsizobufsiz 参数指定用于 TCP 输入和输出的内部 IRIS 缓冲区的大小。在所有支持的平台上,它们可以取 1KB1MB 之间的值。然而,操作系统平台可能使用不同大小的输入和输出缓冲区。如果操作系统平台缓冲区小于 IRIS 缓冲区(例如,64KB1MB),性能可能会受到影响:WRITE 操作可能需要多次访问操作系统才能发送整个 IRIS 缓冲区; READ 操作可能会返回受操作系统缓冲区大小限制的较小块。为获得最佳性能,用户应试验当前操作系统以确定 ibufsizobufsiz 的哪些值可产生最佳结果。

服务器端OPEN命令

处理服务器端 OPEN 时,它会建立一个 TCP 套接字并在套接字上侦听适当端口号上的传入连接请求。端口号要么在参数列表中明确指定,要么从设备名称的数字部分派生。在套接字设置为侦听后,OPEN 立即返回。

如果 OPEN 没有成功,则另一个进程可能已经在该端口号上侦听连接请求。

以下服务器端 OPEN 示例显示了一个设备规范,该规范允许读取和写入最大字符串大小的终止字符串,并使用最大长度读取和写入操作来整合 TCP 通道的使用。

   OPEN "|TCP|4":(:4200:"PSTE"::32767:32767)

此示例中的参数参数如下:因为这是服务器端 OPEN,所以省略了第一个参数(主机名)。第二个参数明确指定端口号 (4200)。第三个参数是模式代码字符。第四个参数(终止符)被省略。第五个参数是输入缓冲区大小。第六个参数是输出缓冲区大小。

在以下示例中,端口号未指定为参数;它源自设备名称的数字部分。此示例打开端口 4200,没有指定参数且超时为 10 秒:

   OPEN "|TCP|4200"::10

服务器端 OPEN 的默认输入缓冲区大小 (ibufsiz) 和输出缓冲区大小 (obufsiz) 参数值为 1,048,576 字节 (1 MB)。

服务器端 OPEN 支持可选的队列大小参数和可选的“G”模式参数。这些选项不可用于客户端 OPEN

服务器端OPEN支持可选的/CLOSELISTEN关键字参数。此选项对于客户端OPEN不可用。

0
0 86
文章 姚 鑫 · 十一月 12, 2024 3m read

第十九章 TCP 客户端 服务器通信 - 数据包模式

数据包模式

如果未指定模式,则默认为数据包模式。如果流模式被禁用,则该模式默认为分组模式。

在分组模式中,只要有一些数据要返回,读取命令就会完成。数据包模式允许在输出缓冲区中构建整个TCP数据段,然后通过发出WRITE*-3WRITE!命令。

如果在没有要发送的字符的情况下发出WRITE*-1来启动一个TCP发送操作,则会收到一个<WRITE>错误。如果发出WRITE OF空字符串,则会收到<COMMAND>错误。

在分组模式下可以发送的字符串的最大长度为1024个字符。如果在未刷新缓冲区的情况下超过此限制,则会收到<WRITE>错误。

因为 TCP/IP 忽略长度为 0 的记录,所以如果在其中没有字符时刷新写入缓冲区,会收到 <WRITE>错误。

在服务器收到连接请求之前,从服务器到客户端的WRITE命令会在服务器上产生<WRITE> 错误。

回车模式(C模式)

此模式修改对输入和输出的回车处理。

在输出时,WRITE ! 生成“CR LF”,而WRITE#生成“CR FF”

在输入时,在启用T模式的情况下,服务器尝试将相邻的CRLF或相邻的CRFF记录为$ZB中的单个终止符。如果CRLF没有在彼此的短时间间隔内到达,则将它们作为单独的终结器进行处理。默认情况下,间隔为1秒。

监控断开模式(D模式)

此模式打开或关闭异步断开监控。通过指定“D”模式字符或/POLLDISCON关键字参数来激活此模式。当指定+D时,将激活TCP断开监视;当指定-D时,将停用TCP断开监视。

当被激活时,IRIS大约每隔60秒轮询一次TCP连接。当检测到断开连接时,IRIS会发出一个<DISCONNECT>错误。在空闲作业中不会发生断开连接检测,例如被挂起命令挂起的作业或等待读取操作的作业。 IRIS在回滚操作期间挂起所有断开监视,以防止发出错误。回滚结束后, IRIS将恢复断开连接监视。此挂起既适用于激活了断开监控的当前TCP设备,也适用于连接到启用了断开监控的TCP设备的未启用断开监控的当前设备。

还可以使用 %SYSTEM.INetInfo 类的 Connected() 方法检查 TCP 断开连接。

转义序列处理模式(E模式)

当设置 E 模式时,输入流中的转义序列被解析并放入 $ZB 特殊变量中。转义序列不得超过 15 个字符,并且必须符合以下语法:

esc_seq::=type1 | type2
type1 ::= '['['0':'?']*['':'/']*{'@':DEL}   
type2 ::= [';'|'?'|'O']['':'/']*{'0':DEL}

这里使用的句法符号表示:

CodeDesc
:x:y 表示 ASCII 序列中从 xy 的指定范围的字符。
``
[ ]指定指定集合的零个或一个成员。
[ ]*指定指定集合的零个、一个或多个成员。
{ }准确指定指定集合的一个成员。

IRIS 发现 ESCAPE 时,它最多等待 1 秒,等待剩余的转义序列到达。如果转义序列与此语法不匹配,或者如果它超过 15 个字符,或者如果有效的转义序列未在 1 秒内到达, IRIS 将部分转义序列放入 $ZB 并设置“BADESC”位( 256) 在 $ZA

0
0 51
文章 姚 鑫 · 十一月 11, 2024 4m read

第十八章 TCP 客户端 服务器通信 - 使用OPEN命令 - Supported参数

Supported 参数

parameters 参数可以是以下格式之一:

hostname
(hostname{:port{:mode{:terminators{:ibufsiz{:obufsiz{:queuesize{:keepalivetime}}}}}}})

parameters 参数中的参数如下:

  • hostname - 可选 — IP 主机的名称、IPv4 协议格式的 IP 地址或 IPv6 协议格式的 IP 地址。指定为带引号的字符串。客户端 OPEN 需要主机名;对于服务器端 OPEN,省略(由占位符冒号表示)。

  • port - 可选 — 如果存在,这是用于连接的 TCP 端口号。如果此端口号为空或省略,则端口号从设备名称的数字部分派生。该参数可以是十进制的端口号,也可以是服务名,提交给本地系统的TCP服务名解析器。

  • mode - 可选——用引号括起来的字母代码字符的字符串。字母代码可以按任何顺序指定;由于 IRIS按从左到右的顺序执行字母代码,因此字母代码之间的交互在某些情况下可能决定首选顺序。默认为数据包模式。模式字符串可以由以下一个或多个字母代码组成:

    • A-接受模式。如果A处于打开状态,则在接受来自客户端作业的连接后,服务器上的初始读取将立即以零长度字符串终止。如果A为OFF,则读取将被阻止,直到超时或数据可用(以最先发生的为准)。
    • C-参见下面的回车模式。
    • D-参见下面的断开模式监控。
    • E-参见下面的转义序列处理模式。
    • G-使端口参数被解释为已打开的数据套接字的套接字描述符。
    • M-流模式下的标准IRIS设备。此模式是调用“PSTE”选项集的快捷方式。它产生了一种设备,其作用类似于标准的 IRIS设备,可用于在两个方向上传递任意行数据。可以打开流模式,以便可以发送或接收任意序列的字符串,而不会使缓冲区溢出。换行符被添加到输出,并从输入中删除。读命令会一直阻塞,直到出现以下情况之一:出现终止符、达到超时时间或已填满指定的读长度。
    • P - 使用记录终止字符填充输出。设置此模式后,WRITE !除了刷新写入缓冲区外,还发送 LF(换行)和 WRITE # 发送 FF(换页)。 WRITE *-3 命令可用于启动缓冲数据的发送,而无需将任何字符插入数据流。请注意 WRITE *-3 只是刷新写入缓冲区而不发送任何终止符,因此不会向接收程序发出数据已完成的信号。 WRITE *-3 更常用于 Wait (W) 模式,不需要终止符。
    • Q—请参阅下面的立即发送模式。
    • S—参见下面的流模式。
    • T—输入端的标准终止符。设置时,CR、LFFF 控制字符用作读取终止符。
    • W—等待模式。在这种模式下,WRITE !WRITE # 命令不会导致 TCP 设备刷新网络输出缓冲区。等待模式导致 TCP 设备等待,直到下一个 WRITE *-3 命令刷新缓冲区并传输数据。
  • terminators - 可选-最多包含八个用户终止符的列表,这些字符将终止在TCP绑定设备上的读取。如果同时指定T模式和终止符,则会忽略T模式。

  • ibufsiz - 可选-输入缓冲区大小。在内部,已从网络读取但尚未传送到 IRIS程序的字符缓冲在可保存ibufsiz字节的数据区中。

  • obufsiz - 可选-输出缓冲区大小。在连续的“SEND”操作之间,TCP设备可以缓冲的最大数据量。发送操作意味着将缓存的数据发送到网络。WRITE!WRITE#WRITE*-3命令可以生成发送操作。

    指定S模式时,会自动生成发送操作,以便在输出缓冲区太满时发送输出缓冲区的内容。但是,在完成消息创建后,程序员仍必须使用其中一个发送操作来确保消息已发送。

    当未指定S模式时,如果写入操作将在缓冲区中放置足够的数据以超过输出缓冲区大小,则会发生<WRITE>错误。请注意,尝试写入本身比输出缓冲区大小更长的字符串总是失败。

  • queuesize - 可选-一个整数,指定有多少客户端作业可以排队等待与服务器的连接。仅用于服务器端打开。默认值为5。最大值取决于TCP实施,但不能超过1000

  • keepalivetime - 可选-(仅限WindowsAIXLinux)允许为此设备设置不同于系统默认的保活计时器。指定使TCP连接保持活动状态的整数秒。有效值介于30432000之间。(432000秒等于5天。)。小于30的值默认为30。如果省略或设置为0,则使用系统范围的默认保活计时器。有关详细信息,请参见/KEEPALIVE关键字选项。

    TCP设备打开时,保活计时器不一定开始计时。它通常在连接已建立时开始计时。也就是说,当初始读取连接已成功完成时。

0
0 88