组织:中国互动出版网(http://www.china-pub.com/)
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:ouyang@china-pub.com
译者:王安鹏(anpengwang    anpengwang@263.net)
译文发布时间:2002-1-9
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但
必须保留本文档的翻译及版权信息。


Network Working Group                                        A. Bogdanov
Request for Comments: 3018                                     NKO "ORS"
Category: Experimental                                     December 2000


统一内存空间协议规范
(RFC3018——Unified Memory Space Protocol Specification)

本文档的状态
本备忘录为Internet社区定义了一种实验性协议,但没有规定任何类型的Internet标准,
需要进一步讨论和建议以便改进。本备忘录的发布没有限制。
版权信息
   Copyright (C) The Internet Society (2000).  All Rights Reserved.
摘要
本文定义的统一内存空间协议(UMSP)用于实现直接访问远程节点的内存。
本文使用的约定
文中使用的关键字“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、
“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY”和“OPTIONAL”的含义
参见RFC2119。文中的语法规范采用RFC2234描述的扩展BNF范式(ABNF)。

目录
1 简介 2
2  UMSP模型 3
2.1  128位地址空间 3
2.2  计算模型 4
2.3  系统架构 5
3  指令格式 6
3.1  指令首部 7
3.2  扩展首部 8
3.3  指令操作数 9
3.4  地址格式 10
4  对指令的响应 11
4.1  RSP, RSP_P 11
4.2  SND_CANCEL 12
5  工作管理 12
5.1   工作初启 13
5.2    启动任务 15
5.3   建立会话连接 16
5.4   关闭会话 19
5.5   终止任务 20
5.6    工作完成 21
5.7   节点的活动控制 23
5.8    不使用会话连接的工作方式 25
6  虚拟机之间交换的指令 26
6.1  数据读/写指令 26
6.2  比较指令 28
6.3  控制传输指令 28
6.4  内存控制指令 29
6.5  其它指令 30
6.6  操作对象 31
7  链 37
7.1 顺序链(Sequence) 37
7.2 事务(Transaction) 37
7.3 分段指令 39
7.4 缓冲 39
7.5 链的确认 40
7.6 基 - 偏移寻址方式 41
8  扩展首部 41
8.1 _ALIGNMENT 41
8.2 _MSG 41
8.3 _NAME 42
8.4 _DATA 42
8.5 _LIFE_TIME 42
9  资源搜索 43
9.1 VM_REQ 43
9.2 VM_NOTIF 44
10 安全性问题 45
11 文中使用的缩略语 45
12 参考 46
13 作者地址 46
14  版权声明 47

1 简介
UMSP是一种面向连接的网络协议,对应于OSI模型中的会话层和表示层。该协议适
用于各种不同类型的系统,从基于专用处理器的简单设备到通用计算机和计算机集群。该协
议采用提供可靠传输服务的传输层协议进行数据交换,但是对于不需要确认数据的传输也可
使用不可靠的传输协议。本文描述了TCP和UDP的使用。
为分布在网络节点上的以128位组织的内存地址空间创建网络环境是UMSP协议的根
本目的。协议定义了连接管理的算法和网络基本指令的格式,但不对节点上的本地内存进行
管理。与传统的网络协议相比,不同节点上的用户程序不再通过网络基本指令的交换相互作
用,或者说不再对数据流工作,而是对远程节点上的虚拟内存直接读写数据或者控制代码的
传输。用户程序不必关心协议和网络的存在,只要使用128位地址指令就可以了。
首先假定在虚拟机(VM)系统上使用UMSP执行伪代码。但是该协议也可在执行处理
器代码组织分布式虚拟地址空间的系统(如集群或者通用计算机)上使用,另外协议的最小
子集可用于没有操作系统的简单设备上。该协议提供了设置连接参数不同的方法,能够建立
高保护级别同时又不影响程序功能的系统。
原则上讲,USMP可以简化分布式系统的开发过程。通过USMP可以在不大幅度增加
程序标准化和开发代价的前提下,把大量、多型计算机上的信息和计算资源统一组织起来。

2  UMSP模型
2.1  128位地址空间
UMSP建立在128位分布式地址内存空间的基础上。128位地址包括网络类型信息、网
络节点地址和本地内存地址,格式如下:
   字节
   0      1                                                    16
   +------+--------------+--------------------+----------------+
   |头部  |     保留     |     节点地址       |    内存地址    |
   +------+--------------+--------------------+----------------+
整个地址长度固定为16个字节。其中:
1)首部(header):1个字节,地址首部字段完整定义了地址格式,其格式如下:
      位
       0     1     2     3     4     5     6     7
      +-----+-----+-----+-----+-----+-----+-----+-----+
      |      地址长度         |  网络类型 | 地址码    |
      +-----+-----+-----+-----+-----+-----+-----+-----+
地址长度(ADDR_LENGTH)共4位,表示网络地址的长度,保存节点地址
(NODE_ADDR)字段中的字节数,不允许是0;网络类型(NET_TYPE)2位,表示节点
所在的网络类型;地址码(ADDR_CODE)2位,本地内存地址的长度编码,这个字段的值
规定了本地内存地址的长度。该字段的取值以及相应的MEM_ADDR字段的长度如下:
            %b00 - 16 bit
            %b01 - 24 bit
            %b10 - 32 bit
            %b11 - 64 bit
头部字段中的这三部分合起来称为地址格式码,明确的定义了节点所在的网络。格式码
的写法是“N  -  - ”,比如N 4-0-2表示节点网络地址长度为4个字节而内存地址为32位。
在本文中网络类型0表示该地址格式是为IPv4网络定义的。如果网络类型是0,在书写时
可以省略,比如N 4-0-2和N4-2 是等价的。如果网络类型和地址码都是0那么可以全部省
略不写,格式码就可以用一个数字表示。必须为每个全局网络指定一个或多个地址格式码,
即使单一系统也必须如此。
2)自由(FREE):0到12个字节,本协议没有使用这个字段,可以在这个字段中保存
节点内存控制系统所需要的信息。如果该字段没有使用,则所有的字节都必须设为0。加入
这个字段是为了保证网络指令必须使用16字节地址格式,而不能使用本地内存的短地址格
式。
3) 节点地址(NODE_ADDR):1到13个字节,每种地址格式码都单独定义了该字段
的格式。节点地址不一定与实际的网络地址完全一致,如果网络地址很长,就需要在网络内
组织一个能够支持UMSP地址的子集。
4) 内存地址(MEM_ADDR):16/24/32/64位,本地内存地址。该字段保存节点地址
所指定系统的内存地址,节点负责控制自身的内存。本协议没有定义该字段的使用顺序和格
式。
对于用户程序而言,这个128位地址是一个整体,用户代码并不了解所访问内存的物理
地址。像数据一样,128位内存地址也可以在节点之间传输,比如通过函数的参数缓冲区或
者复制数据的指令。因此对于所有节点而言每个节点必须是唯一标识的。并没有把实际的网
络和128位地址联系起来的具体算法,因此必须预先知道所使用的地址格式。
由于UMSP拥有自己的地址空间,因此能够把多个全球性网络统一起来。节点可以通
过内部的本地网或者下一级的可定地址设备与不使用网络通信的节点连接。地址格式码确定
的每个节点必须能够定义通过该地址时的网关响应方式。
2.2  计算模型
计算模型分为三层:工作、任务和控制线程。工作代表用户程序,工作是分布式的,可
以同时在多个节点上运行。工作控制由称为工作控制点(JCP)的节点集中执行,一个JCP
可以控制多项工作。JCP可以放在创建一项工作的同一个节点上,也可放在其他编址的网络
节点上。任务是工作在各节点上的表示,任务包括一个或多个控制计算线程。每项工作在同
一个节点上只能有一个任务。相应的用户程序结束后工作也就完成了,工作结束时它在各个
节点上的任务也同时完成。
工作拥有单独的128位地址空间。地址空间采用分段组织方式,一段就是一个节点的本
地内存。此外,本协议允许采用对象工作方式,对象就是节点上相互关联的单独的内存。
任务线程代表具体的特定节点上虚拟机执行的控制线程,该线程可以访问该项工作128
位地址空间内的任何地址。控制从一个(远程)节点转移到一个新地址,意味着在该地址所
属远程节点上创建一个新的线程。连续的代码段不能分布到多个节点上。另外,也不可能从
多个节点上获得分布式的连续内存空间。
本协议并不要求各虚拟机节点支持不涉及跨越不同内存空间的不同任务,也没有强制要
求对多线程的支持。
本协议定义了全局工作标识符(GJID),它由控制该项工作的JCP分配。任何时刻在这
个一体化系统中所有处于激活状态的GJID都是唯一的。工作可以包含不同类型的VM代码,
不同类型的虚拟机可以放在一或多个节点上。由于规定了一个节点上不同虚拟机类型的成组
关联机制,因此在特定的工作上下文中非标准代码也可以在节点上执行。第9章将详细讨论
成组技术。虚拟机和组必须在常规内存空间中工作(使用内存管理的常规子系统)。

2.3  系统架构
基于虚拟机的系统架构如下图所示:

             节点 1                              节点 2
             --------                            --------

      +--------------------+              +--------------------+
      |      用户程序1    |               |      用户程序1    |
      +-----------------------+           +-----------------------+
         |      用户程序N    |               |      用户程序N    |
         +--------------------+              +--------------------+

   +-----+  +-----+       +-----+      +-----+  +-----+       +-----+
   | VM1 |  | VM2 | . . . | VMn |      | VM1 |  | VM2 | . . . | VMn |
   +--+--+  +--+--+       +--+--+      +--+--+  +--+--+       +--+--+
      |        |             |            |        |             |
    +--------------------------+        +--------------------------+
    |                          |        |                          |
    | +-----+  U M S P         |        |          U M S P         |
    | | JCP |                  |        |                          |
    | +-----+                  |        +-------------+------------+
    +-------------+------------+                      |
                  |                             +-----+-----+
            +-----+-----+                       |    TCP    |
            |    TCP    |                       +-----+-----+
            +-----+-----+                             |
                  |                                   |
                  +-----------------/                 |
                                   /------------------+
                                  /
                                  |
                            +-----+-----+
                节点 N      |    TCP    |
               --------     +-----+-----+
                                  |
                     +------------+------------+
                     | +-----+                 |
                     | | JCP | U M S P         |
                     | +-----+                 |
                     +-------------------------+

         图1:基于虚拟机(VM)的系统结构
一个或多个虚拟机在UMSP的高层工作,虚拟机的层并不是网络层,最后一层网络层
是UMSP。因此虚拟机层并没有自己的网络成分,它与UMSP使用同一个操作码字段。该
协议的最终服务用户是用户代码,用户代码运行在虚拟机上。用户代码采用128位地址指令,
虚拟机把这些指令转化成网络命令,转化通过在远程机器上运行的UMSP协议完成。虚拟
机内部组织、命令系统和API可以是任意的。协议定义的仅仅是虚拟机可以通过网络交换
的基本格式。
协议没有对工作所使用的内存进行控制,内存孔应该由虚拟机完成。如果一个节点上运
行了多个虚拟机,它们既可以共享内存空间也可以用互相隔离的内存空间。
UMSP使用可靠的网络传输层协议传输数据,本文定义了TCP的使用。对于不需要确
认数据的传输可以使用UDP。因此连接的建立必须使用TCP,本文假定使用多路TCP的多
重连接技术,传输连接控制不在本文的讨论范围之内。
UMSP指令不含收端和发端的网络地址,协议要求单地址的UMSP必须与一个传输层
地址对应。因此,必须让128位内存地址唯一确定一个传输层的节点地址。除了TCP之外,
也可使用其它的传输协议或者非网络通信方式,但必须满足以下要求:
? 可靠的传输,传输层必须告知交付与否;
? 允许改变传输段的先后顺序;
? 不允许重复发送同一个段;
? 在节点突然发生重载时必须保证能够确认重载前分配的与会话连接相关的段;
? 允许使用非连接方式。
虚拟机是独立的程序,只有执行128位地址指令涉及到其它节点时才需要适用本协议。
虚拟机可以执行多项用户任务,每个任务可以包含多个控制线程。虚拟机必须能够把128
位地址的程序指令解释成几条UMSP协议指令。交换数据的节点之间打开会话连接,每个
连接只与一个工作相关,两个节点之间可能同时打开多个用于不同工作的会话连接。此外,
协议也提供了无连接的数据交换。
? UMSP节点之间的交换可以包含以下类型的指令:
? 直接内存访问;
? 请求分配/释放内存;
? 比较指令;
? 子程序调用与无条件跳转指令;
? 同步指令;
? 对象操作指令——访问对象内存或者执行对象过程。
UMSP不跟踪用户控制线程,虚拟机必须自行确定指令的执行次序。UMSP指令的长度
不依赖于传输层的分段长度,分段是为了传输长指令。短指令封装在一个分段中传输,可能
还要压缩标题。分段最小6个字节,要实现所有的功能则需要54个字节。

3  指令格式
USMP指令包括基本头、扩展头和操作数,所有各部分的长度都是可变的。
   +----------------+----------------------+------------------------+
   |     首部       |       扩展首部       |          操作数        |
   +----------------+----------------------+------------------------+
首部包括操作码和解释命令所需要的信息。扩展首部是可选的,包括基本首部没有定义
的附加信息。操作数包括指令数据。不需要了解不同操作码的定义,通过指令格式可以计算
一般的指令长度此外。为了保证在不同网络速度下协议能够有效地工作,指令首部提供了简
短和扩充两种格式。此外还提供了一种首部压缩的简单算法。所有的指令和扩展首部的标识
符以大写字符给出,指令标识符的第一个字符必须是字母,扩展首部的标识符以下划线开始。

3.1  指令首部
首部格式如下:
    字节:
       +0                              +1
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   0: |            OPCODE             |ASK|  PCK  |CHN|EXT| OPR_LENGTH|
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   2: |                        OPR_LENGTH_EXT                         |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   4: |                         CHAIN_NUMBER                          |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   6: |                         INSTR_NUMBER                          |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   8: |                                                               |
      +                          SESSION_ID                           +
      |                                                               |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   12:|                                                               |
      +                            REQ_ID                             +
      |                                                               |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1) 操作码(OPCODE):占用一个字节,这个字段的值取决于指令。操作码的值分为
以下几段:
             1 - 112  管理指令
           113 - 127  保留
           128 - 223  虚拟机之间的交换指令
         0, 224, 255  保留
2) 应答请求(ASK):1位,表示是否必须响应,规定了首部中是否要包含REQ_ID
字段。如果ASK=1,则指令中包含REQ_ID字段,否则不出现该字段。
3) 压缩(PCK):2位,首部压缩属性。该标志用于压缩在一次TCP连接中传输的指
令首部或在UDP分组中发送的多条指令。使用该标志是基于这样的假定,即前后两条指令
属于同一次会话连接,或者(更可能)属于一个链。该标志的取值及含义如下:
%b00 – 该指令属于待定的会话,该指令不含CHAIN_NUMBER、INSTR_NUMBER和
SESSION_ID字段。
%b01 – 给定指令与前一指令属于同一次会话连接,指令首部没有SESSION_ID字段。
%b10 – 给定指令与前一指令属于同一连接、同一链,该指令首部没有
CHAIN_NUMBER、INSTR_NUMBER和SESSION_ID字段,前一指令的INSTR_NUMBER 
加上1即得到该指令的INSTR_NUMBER值。
%b11 – 给定与前一指令可能不属于同一会话,必出现SESSION_ID字段,字段
CHAIN_NUMBER与INSTR_NUMBER是否出现依赖于CHN标志。
3) 链(CHN):链标志占用1位。在一次会话连接中传输的或者从属于同一工作的指
令可能组成链,关于链详细地讨论参见第7章。如果SEQ=1,则该指令与一条链相关,并
包含CHAIN_NUMBER和INSTR_NUMBER (如果PCK不是%b10)字段。如果CHN = 0,则
该指令没有相关的链,也没有CHAIN_NUMBER和INSTR_NUMBER字段。
4) 扩展(EXT):1位,表示指令中是否出现扩展首部。如果EXT=1则表示存在一个
或多个扩展首部,否则没有。
5) 操作数长(OPR_LENGTH):3位,操作数字段的字(32位)数。如果值为0就表
示没有操作数,如果值为%b111则表示采用扩展首部格式。在扩展首部格式中,操作数的长
度由OPR_LENGTH_EXT决定而不是OPR_LENGTH。
6)扩展操作数长(OPR_LENGTH_EXT):2字节,操作数字段的字(32位)数。只有
当OPR_LENGTH =%b111时才出现字段OPR_LENGTH_EXT,否则该字段不会出现。如果
OPR_LENGTH_EXT = 0则表示没有操作数。使用OPR_LENGTH_EXT字段有几个原因:
操作数的长度可能超过24个字节(6个字);采用4字节对齐格式比2字节的压缩首部效率
更高。
7) 链数(CHAIN_NUMBER):2字节,链的个数。该字段保存给定指令相关的链个
数,值%x0000和%xFFFF保留不用。
8) 指令号(INSTR_NUMBER)2字节,指令在链中的序号,从0开始计数,%xFFFF
保留不用。
9) 会话号(SESSION_ID):4字节,它是指令受方分配的会话连接标识符。在会话连
接中双方在连接中都设定自己的标识符并通知对方。如果值为0则表示指令不属于任何确定
的会话,值%xFFFFFFFF保留不用。
10)请求号(REQ_ID):4字节,请求标识符,用于建立请求及其响应的对应关系。
另外,描述指令格式也要用到标识符OPR_LENGTH,如果OPR_LENGTH = %b111则
需要使用OPR_LENGTH_EXT字段。如果指令操作数的长度不超过24字节,即可以使用2
字节的短格式(OPR_LENGTH < > %b111)与首部一起传送,也可以使用4字节的扩展格
式(OPR_LENGTH = %b111),两者是等价的。 

3.2  扩展首部
如果指令首部的EXT标志设为1,则指令包含一个或多个(最多30个)扩展首部,扩
展首部用于:传送基本首部没有包含的服务信息;如果一条指令中的数据超过262240字节,
则用于传送数据长度。一般格式如下:
   字节:
       +0                              +1
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   0: |HXT|       HEAD_LENGTH         |       HEAD_LENGTH_EXT         |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   2: |                   continued HEAD_LENGTH_EXT                   |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   4: |HSL|HOB|HRZ|     HEAD_CODE     |         HEAD_CODE_EXT         |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   6: |                           RESERVED                            |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   8: |                                                               |
      /                             DATA                              /
      /                                                               /
      |                                                               |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1) HXT:1位,规定数据长度字段的长度。如过HXT = 0,则扩展首部的长度
由字段HEAD_LENGTH确定,此时没有HEAD_LENGTH_EXT字段。如果
HXT = 1,则首部长度由字段HEAD_LENGTH和HEAD_LENGTH_EXT一
起决定。
2) HEAD_LENGTH:7位,数据字段的字(16位)数。如果HXT = 0,则这7
位就是一个独立的字段,否则是整个长度字段的高7位。
3) HEAD_LENGTH_EXT:3字节,数据字段的字(16位)数。如果HXT = 0,
则没有该字段,否则作为长度字段的低位。
4) HSL:1位,最后一个首部标志,指令中的最后一个扩展首部此位设1,其他
都是0。
5) HOB:1位,强制处理标志。如果受方节点不知道扩展首部的目的或者由于
某种原因无法处理,则该位定义了处理指令的顺序。如果HOB = 1则不执行
指令,否则没有任何影响。协议必须处理所有的扩展首部,无论是否出错。
6) HRZ:1位,保留以备日后扩展之用。根据协议,受方不得处理该位,发方
须将其设为0。
7) HEAD_CODE:5位。如果HXT = 0,则该字段保存扩展首部编码,否则加
入HEAD_CODE_EXT字段。它是首部编码的高位。
8) HEAD_CODE_EXT:1字节,如果HXT = 0,则该字段不出现,否则作为首
部编码的低位出现。
9) RESERVED:2字节,如果HXT = 0,则该字段不出现,否则保留以备后用。
按照协议,在现在的实现中受方不得处理该字段,发方须将其设为0。
10) DATA:扩展首部的数据字段。= 0,则该字段的长度为0——254字节,否则
为0——4*10^9字节。该字段的格式取决于首部编码的值。
对于受方而言,必须按照扩展首部在指令中出现的顺序进行处理,如果一条指令包含的
扩展首部超过30个则认为是错误的。在收到这样的指令后必须断开传送该指令的会话。标
识符HEAD_LENGTH 和HEAD_CODE更多地用于扩展首部格式的描述,如果HEX = 0,
则使用字段HEAD_LENGTH + HEAD_LENGTH_EXT和HEAD_CODE +   
HEAD_CODE_EXT。编码为0-30的3首部既可用短格式(HEX=0)又可用扩充格式(HEX=1)
传送。

3.3  指令操作数
操作数字段包括指令数据,操作数字段长度由OPR_LENGTH或者 
OPR_LENGTH_EXT乘以4得到。如果需要可以在该字段的尾部填充1-3个0字节。操作数
的最大长度是262140字节。如果需要使用更长的数据,则应用扩展首部。操作数的格式由
指令决定。
3.4  地址格式
以下地址格式数据用于定义直接连接到全局性Ipv4网络上的节点:
      N 4-0-0 (4)
      N 4-0-1 (4-1)
      N 4-0-2 (4-2)
相应的128位地址格式为:
   字节:
      +0              +1              +2              +3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   0: |0 1 0 0|0 0|0 0|                   Free                        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   4: |                              Free                             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   8: |            Free               |           IP address          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   12:|           IP address          |      Local memory address     |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   0: |0 1 0 0|0 0|0 1|                   Free                        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   4: |                              Free                             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   8: |     Free      |                  IP address                   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   12:|   IP address  |             Local memory address              |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   0: |0 1 0 0|0 0|1 0|                   Free                        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   4: |                            Free                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   8: |                         IP address                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   12:|                     Local memory address                      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1) Free:本协议未使用该字段。
2) IP 地址:设定全局Ipv4网络上的节点地址。
3) 本地内存地址(Local memory address):参见第2.1节。
IP地址唯一确定了给定类型的节点,这些节点之间的交互使用TCP协议。如果发送无
需应答的指令也可使用UDP。IANA分配给TCP和UDP的端口是2110,监听方(受方)必
须打开该端口。TCP节点初始化打开的连接后(或者UDP节点)可以使用任何端口传送分
组。本文假定可以利用多路技术打开多个TCP连接。

4  对指令的响应
本协议把指令分为两类:在UMSP层(操作码为1-112)上传输的管理指令和虚拟机之
间交换的指令(操作码为128-223)。处理这两类指令的区别在于:前一类指令的请求标识
符REQ_ID字段是协议定义的,后者则是虚拟机定义的;收到第一类指令的响应后,协议
必须分析其REQ_ID,与前面发送的指令相比较,对于后者则无须如此,因为这些指令只是
发送给虚拟机的。
响应指令的ASK字段设为1,就是说其首部必有REQ_ID字段,REQ_ID字段的值取
自该指令所响应的原指令,响应指令不需要响应。
节点山可能有几个虚拟机连接到协议,每个虚拟机都有自己的工作地址空间。对不同虚
拟机的请求有可能同时发生,因此指令要通过两个字段来识别:连接到确定虚拟机的会话标
识符SESSION_ID和请求标识符REQ_ID。
4.1  RSP, RSP_P
“应答”(RSP)和“协议应答”(RSP_P)指令的格式是相同的,区别只是操作码不同。
      OPCODE = 129/1   ;分别是RSP和RSP_P的操作码
      ASK = 1
      PCK = %b01/11
      EXT = 0/1
      CHN = 0
      OPR_LENGTH = 0/1
      SESSION_ID 和REQ_ID – 值取自响应的原指令。
      操作数:
         2字节:基本返回码。
         2 字节:附加的返回码。
      可选的扩展首部:
         _MSG – 包含任何出错信息的描述。
该指令如果没有操作数则表示正响应,相当于基本返回码和附加返回码的值都是0。取
0值的基本返回码表示正响应,正响应的附加返回码不一定是0。基本返回码如果取非0值
表示负响应,基本返回码定义了错误的类型,附加返回码则指明什么错误。
RSP指令用于虚拟机响应,返回码必须从虚拟机得到,如果协议无法传送所需的虚拟机
响应指令,则单独构造一个负响应RSP。指令RSP_P总是在UMSP层构造的,如果协议不
能定义RSP_P在什么指令上传输,则不执行任何动作。

4.2  SND_CANCEL
发送很长的分段指令或者事务时,可能在部分数据已经发出并存储到接收方的缓冲区后
需要取消发送,为此,协议提供了“取消发送”(SND_SEND)指令,格式如下:
      OPCODE = 2
      ASK = 0
      PCK = %b01/10/11
      EXT = 0/1
      CHN = 1
      OPR_LENGTH = 1
      SESSION_ID – 该值取自取消链。
      CHAIN_NUMBER – 链序号,指明要取消哪次发送。
      INSTR_NUMBER – 总是为0。
      操作数:
         2字节:基本返回码。
         2 字节:附加的返回码。
      可选的扩展首部:
         _MSG – 包含任何出错信息的描述。
指令SND_CANCEL用于取消部分已经传输的事务或者片段指令,收到该命令后,传送
链中已经收到的数据全部丢弃。

5  工作管理
工作管理的功能包括:初始化和完成工作;初始化和完成任务;打开/关闭会话连接;
控制激活节点。操作码在1-112之间的指令用于工作管理,这些指令必须通过TCP传输,
即使不需要响应也不能使用UDP。
UMSP采用任务集中控制的工作模型,因为在分散系统中显然不能使用指示字控制。任
务完成的时间是不确定的,结点也随时可能重载,无法保证指示字能够传达到执行工作的分
散系统的所有其它节点上。由于工作仍在继续,与该项工作相关的任务可能又在同一节点上
启动。新的任务可能要分配新的动态资源。新分配的资源地址可能与该任务启动之前已经分
配的资源地址发生交叉。已经过时的指示字可能还保存在其他的节点上,但是尽管形式上正
确,却实际指向了其他的节点。如果无法控制程序的工作就可能造成这种情况。
为了完成交付的工作,UMSP必须:明确定义任务结束的节点;如果某个节点上的任务
在整个工作完成之前已经结束,那么必须通知执行该工作的所有节点;同一个节点上可以多
次初始化任务,但是第一个任务完成时必须通知所有的节点。协议不控制指示字,虚拟机负
责保证指示字的正确性。为此,虚拟机必须有某种结构能够把128位的指示字保存在特殊的
内存区域。在某项任务结束整个工作时协议须通知节点周围的虚拟机,虚拟机则把与该任务
有关的指示字都设为无效,因此对这些指示字的访问是独占的。如果应用程序提供了例外处
理机制,则或者维持工作的能力,或者结束事故状态。这种决策方式可以排除不能控制的程
序。
为了处理UMSP层的具体问题,协议为每项工作定义了控制工作的节点,称为控制工
作节点JCP。JCP既可以是工作启动的节点,也可以是其他的专用节点。JCP的主要功能是
跟踪工作任务的初始化和结束。此外,专用JCP还用于统一的用户验证和防范攻击。
对于工作和任务控制以下标识符是确定的:
1)本地任务标识符(LTID),分配给节点每个活动任务。LTID的长度等于该节点定义
的本地内存地址长度,任何时候节点上所有LTID的值必须是唯一的。已经完成的任务,期
LTID可以赋给新启动的任务。
2)JCP为工作的各项任务分配一个控制任务标识符(CTID),其长度等于JCP节点的
本地内存地址的长度。任何时候JCP定义的所有CTID都必须是唯一的。与LTID相比,CTID
的选择有一些限制。
3)分配给每项任务的全局任务标识符(GTID),格式与节点内存的128位地址相同,
在LTID上代替本地内存地址。
4)分配给各项工作的全局工作标识符(GJID),GJID在JCP节点上定义,格式与JCP
节点上的128位内存地址相同。工作的第一项任务的CTID中本地内存地址被替换。GJID
用于所定义的控制工作的会话连接的打开过程。
LTID和CTID写入指令中长为2/4/8字节的字段,如果指令中的标识符字段比这些标识
符长则,标识符写在后面的字节中。这些字节的最高位必须是0。如果收到的LTID(CTID)
比本地内存地址短,则需要在高位字节填充0。GTID和GJID写入指令中长为4到16字节
的字段,这些标识符中不含FREE字段,FREE字段中的所有字节都被视作0。标识符的长
度在地址首部定义。
发送指令CONTROL_REQ、TASK_REG和SESSION_OPEN时,协议采用超时机制。
超时值由节点设定,但是至少为传输层的最大传输时间间隔的三倍,超时值不影响传输层队
列的等待时间。

5.1   工作初启
工作与虚拟机上执行的用户程序有关,UMSP工作的初始化可以在程序用户开始时或者
运行中进行。工作相关的任务与工作同时在节点上初始化,并指定相应的LTID。如果装载
用户程序的节点被选作JCP,那么工作初始化的问题就超出了网络协议的范围。考虑到以下
原因,可以选择其他的节点作JCP:工作初始化节点通过低速或者超载的通道连接网络,该
通道不适于传输管理信息;节点没有传输管理表的计算能力;必须逐个验证所有的节点。如
果选择其它节点作JCP,那么工作启动的节点必须到JCP上登记该工作。
5.1.1   CONTROL_REQ
指令“请求控制”(CONTROL_REQ)从工作启动的节点发送到作为JCP的其它节点,
格式如下:
      OPCODE = 3
      PCK = %b00
      CHN = 0
      ASK = 1
      EXT = 0/1
      OPR_LENGTH = 2/3  ;依赖于LTID的长度。
      REQ_ID – 由发送方节点协议指定,在应答中发送。
      操作数:
         4 字节:控制参数文档,格式如下:
            位
             0     1     2     3     4     5     6     7
            +-----+-----+-----+-----+-----+-----+-----+-----+
            |                                               |
            +                 JOB_LIFE_TIME                 +
            |                                               |
            +-----+-----+-----+-----+-----+-----+-----+-----+
            | CMT |    Reserved     |        VERSION        |
            +-----+-----+-----+-----+-----+-----+-----+-----+
            |                   Reserved                    |
            +-----+-----+-----+-----+-----+-----+-----+-----+
JOB_LIFE_TIME:2字节,工作的生存期(以秒计),如果为0表示不使用工作生存期
限制。
CMT:1位,多JCP标志,保留作以后的协议扩展使用。
VERSION:1字节,UMSP版本号,必须是1。
Reserved:3+8位,都必须置0。
         4或8字节,工作启动节点(该指令的发送方)所分配的任务LTID。
可选的扩展首部:
_JOB_NAME  - 该首部保存工作名称,只能指定一次以后不可改变。
_INACT_TIME – 保存不活动时间(参见第5.7节)。
收到CONTROL_REQ指令后,JCP首先从接收的指令中检查LTID并作如下处理:
1) 如果发送CONTROL_REQ的节点已经使用那个LTID在JCP上进行了注册,则
发出注册工作非正常结束的消息,参见第5.5.2节(即认为该节点已经重启),
然后批准启动新的工作。
2) 如果没有使用收到的LTID注册的节点,立即允许启动新工作。
如果JCP确认该项控制,则发送CONTROL_CONFIRM指令,否则发送 
CONTROL_REJECT指令。

5.1.2     CONTROL_CONFIRM
指令“确认控制”(CONTROL_CONFIRM)作为JCP对CONTROL_REQ指令的正响
应发出,格式如下:
      OPCODE = 4
      PCK = %b00
      CHN = 0
      ASK = 1  ;该指令不需要应答,这个标志仅仅说明必有REQ_ID字段。
      EXT = 0/1
      OPR_LENGTH = 1-4  ;取决于GJID的长度。
      REQ_ID – 取自CONTROL_REQ指令。
      操作数:
         4-16字节:JCP分配的工作GJID
发送CONTROL_REQ指令意味着控制请求和任务请求的开始,分配的任务CTID是
GJID的一部分(本地内存地址字段)。

5.1.3     CONTROL_REJECT
指令“拒绝控制”(CONTROL_REJECT)作为JCP对CONTROL_REQ指令的负响应
发出,格式如下:
      OPCODE = 4
      PCK = %b00
      CHN = 0
      ASK = 1.  ;该指令不需要应答,这个标志仅仅说明必有REQ_ID字段。
      EXT = 0/1
      OPR_LENGTH = 1/2  ;取决于是否包含控制参数文档字段。
      REQ_ID –取自CONTROL_REQ指令。
      操作数:
         2字节:基本错误码,不能是0。
         2 字节:附加错误码。
         4 字节:控制参数文档(参见第5.1节),可选。
可选扩展首部:
         _INACT_TIME – 保存不活动时间(见第5.7节)。
         _MSG – 任意的错误描述。
5.2    启动任务
工作同时在多个节点上执行,相应的任务必须在每个节点上初始化,对于每项工作一个
节点上只能有一个与其相关的任务,一个任务只能与一个工作相关。创建工作的节点上任务
和工作的初始化同时进行,其它节点在第一次收到与该工作相关的会话连接请求后初始化任
务。打开会话连接的请求包含GJID字段,该字段含有JCP地址。启动任务必须得到JCP的
认可,但如果启动会话连接的请求来自JCP就不要请求批准。

5.2.1     TASK_REG
指令“注册任务”(TASK_REG)由启动任务的节点向远程的JCP节点发出,格式如下:
      OPCODE = 6/7/8 ; 对应于2/4/8字节的CTID 
      PCK = %b00
      CHN = 0
      ASK = 1
      EXT = 0/1
      OPR_LENGTH = 2-8  ;取决于GTID和LTID的长度。
      REQ_ID – 由发送方节点协议分配并在应答中发送。
      操作数:
         2/4/8字节:工作启动任务的CTID,是指令SESSION_OPEN中LTID的部分。
         4-16 字节:GTID,由启动会话连接的节点分配。GTID由发送方地址(传输
层上的地址)和指令SESSION_OPEN中的LTID字段组成。
         2/4/8 字节:LTID,由启动任务的节点分配(该指令的发送方)
      可选的扩展首部:
         _INACT_TIME – 保存不活动时间(见第5.7节)。
只有给定GJID的任务还没有在节点上启动时才能发送TASK_REG命令。JCP根据以
下条件决定是否启动任务:收到的GTID任务已经在JCP上注册;节点请求启动的任务LTID
还没有注册。如果不满足这两个条件,JCP就不能批准该项任务。如果JCP批准了任务启动,
就发送TASK_CONFIRM指令,否则发出TASK_REJECT指令。

5.2.2     TASK_CONFIRM
指令“任务确认”(TASK_CONFIRM)作为JCP对TASK_REQ指令的正响应发出,格
式如下:
      OPCODE = 9
      PCK = %b00
      CHN = 0
      ASK = 1. ;该指令不需要应答,这个标志仅仅说明必有REQ_ID字段。
      EXT = 0/1
      OPR_LENGTH = 1/2  ;取决于CTID的长度。
      REQ_ID – 取自TASK_REG指令。
      操作数:
         4/8 字节:JCP为该任务分配的CTID。
      可选的扩展首部:
         _JOB_NAME – 工作名。

5.2.3     TASK_REJECT
指令“任务拒绝”(TASK_REJECT)作为JCP对TASK_REQ指令的负响应发出,格式
如下:
      OPCODE = 10
      PCK = %b00
      CHN = 0
      ASK = 1. ;该指令不需要应答,这个标志仅仅说明必有REQ_ID字段。
      EXT = 0/1
      OPR_LENGTH = 1
      REQ_ID – 取自CONTROL_REQ指令
      操作数:
         2 字节:基本错误码,不能为0。
         2 字节:附加的错误码。
      可选的扩展首部:
         _INACT_TIME –非活动状态时间(见第5.7节)
         _MSG – 任意的错误说明。

5.2.4     TASK_CHK
为了保证安全,即使任务启动后,收到打开会话连接请求的节点也可能要到JCP上对
启动连接的节点进行核实。“任务检查”(TASK_CHK)指令由收到建立会话连接指令
SESSION_OPEN的节点 JCP向发出。拥有该GJID的任务必须已经在该节点上存在。该指
令格式与TASK_REG类似,操作码是11,JCP同样使用TASK_REG指令应答。如果收到
的任务GTID和LTID已经在JCP上注册则发出确认指令。该指令是可选的。

5.3   建立会话连接
会话连接在同一工作的两个任务之间建立。会话连接由虚拟机自发建立,用于在虚拟机
之间交换指令。一个会话连接只能与节点上的一项任务有关,该任务可能与不同的节点建立
多个连接,对于每个GJID两个节点之间只能由一个会话连接。建立会话连接的请求命令包
含工作的全局标识符GJID。如果收到建立连接指令的节点上还没有该GJID,虚拟机就创建
新的任务,如果GJID所标识的任务已经启动,则不创建新任务。
会话连接必须通过TCP建立,但是连接建立后,如果指令的发送方不需要应答,也可
使用UDP。多个会话连接可以使用同一个TCP连接,一个会话连接也可使用多个TCP连接。
协议允许不建立会话连接的工作方式,但是节点必须有默认的虚拟机,并且虚拟机部通过连
接也可执行指令。
在建立会话连接时,双方就使用的虚拟机类型和实现的协议功能子集达成一致。会话连
接UMSP可以是不对称的,就是说连接的上方可以采用不同类型的虚拟机,提供不同的功
能子集。如果建立的会话连接中虚拟机类型为0,则表示成组虚拟机(见第9章),实际的
虚拟机类型不能是0。建立会话连接可能需要2到8次握手。

5.3.1     SESSION_OPEN
指令“打开会话”(SESSION_OPEN)用于启动会话连接并设置我手中使用的连接参数。
格式如下:
      OPCODE = 12
      PCK = %b00/11  .第一个指令(启动)取%b00,以后都是%b11。
      CHN = 0
      ASK = 1
      EXT = 0/1
      OPR_LENGTH = 6 - 10  ;取决于GJID和LTID的长度。
      SESSION_ID – 第一条指令该字段为空, 此后是接收方指定的会话标识符。
      REQ_ID – 指令发送方指定的会话连接标识符。
      操作数:
         2 字节:接收方需要的虚拟机类型。
         2 字节:接收方需要的虚拟机版本。
         4 字节:接收方需要的连接文档。
         2 字节:发送方的虚拟机类型。
         2 字节:发送方的虚拟机版本。
         4 字节:发送方给出的连接文档。
         2 字节:发送方为会话分配的缓冲区大小(以256字节组成的块为单位),0
表示没有缓冲区。
         4-16 字节:GJID。
         4/8 字节:发送方节点指定的任务(在发送方上)LTID,作为GTID字段的
一部分用于指令TASK_REG。
如果接受方所要求的虚拟机类型和版本是0,接收方节点自行选择选择虚拟机类型并在
应答中给出说明,连接的建立必须绑定某个虚拟机或者虚拟机组。
在连接的建立中最多一共可以传输7个SESSION_OPEN指令,指令SESSION_ACCEPT
作为建立连接请求的应答指令,如果拒绝建立连接则使用SESSION_REJECT指令。其中的
任何一个步骤都可拒绝连接的建立,但是要么批准连接,要么在第8次请求之前明确拒绝。
连接过程中部分参数可能改变:虚拟机类型和版本,连接文档。如果反复收到来自某个节点
的打开会话连接的请求,而请求中的GJID已经被原来建立的连接使用,那么可以视情况作
以下处理:
1) 如果请求来JCP,则必须:紧急结束原来的任务并时占用的动态资源;无需请
求JCP确认启动新的任务;同意建立连接。
如果请求来自其他的节点则应拒绝建立新的会话连接,不必改变现有的任务。

5.3.2     SESSION_ACCEPT
指令“接收会话”(SESSION_ACCEPT)是建立会话连接请求的正响应,格式如下:
      OPCODE = 13
      ASK = 1
      PCK = %11
      EXT = 0/1
      CHN = 0
      OPR_LENGTH = 0
      SESSION_ID – 接收方指定的会话连接标识符。
      REQ_ID – 发送方分配的会话连接标识符。

5.3.3     SESSION_REJECT
指令“拒绝连接”(SESSION_ACCEPT)是建立会话连接请求的负响应,格式如下:
      OPCODE = 14
      ASK = 0
      PCK = %b11
      EXT = 0/1
      CHN = 0
      OPR_LENGTH = 1
      SESSION_ID – 接收方指定的会话连接标识符。
      操作数:
         2字节:基本错误码,不能是0。
         2 字节:附加错误码。
      可选的扩展首部:
         _MSG – 任意的错误说明。
5.3.4   连接文档(Profile)
链接文档用4字节的标志字段定义,该标志分为32个标识符S0-S31,标识符中的数字
表示位的序列号。如果设为1则提供对应的功能,否则不(或者不一定)提供对应的功能。
会话连接中所建立的功能列表详述如下:
与链有关的:
      S0 – 使用分段指令
      S1 – 使用序列
      S2 – 使用事务
与建立连接有关的:
      S3 – 使用无连接的数据交换
      S4 – 使用建立连接的数据交换
指令格式:
      S5  - 保留,必须是0
      S6  - 交换指令中使用16字节地址
      S7  - 允许使用压缩的指令首部(OPR_LENGTH < > %b111)
      S8  - 允许使用扩展格式的指令首部 (OPR_LENGTH = %b111)
      S9  - 对于数据字段不超过254字节的指令使用扩展首部
      S10 – 对于数据字段不超过4*10^9字节的指令使用扩展首部
      S11-S15  操作数种数据字段的最大长度(4字节字),这些位是公用的。如果用
字节计算,等与该字段的值加1再乘上4。如果这4位是1111,则数据字段的最大长度由指
令格式定义。
      S16-S19  这些位是通用的。如果表示指令受方的需求连接文档,这些位保存
UMSP版本号(必须是%b0001)。如果表示发送方的连接文档,该字段保存工作的优先级。。
工作优先级用于:工作指令发送到传输层的队列;设置在传输层上的优先级;设置任务计算
的优先级。
      S20 – 指明是否采用4字节定界方式,如果S16 = 1,则:
         (1)  OPR_LENGTH = %b111
         (2)  所有的扩展首部和操作数字段都从4的倍数开始。
         (3)  如果需要每个首部的后面填0。
      S21 – 使用对象的过程名。
      S22 – 使用对象名。
可以执行那些指令:
      S23 – 可以响应虚拟机上执行的操作(指令RSP)。
      S24 – 使用数据读取和比较指令。
      S25 – 使用数据写入指令。
      S26 – 使用控制传输指令。
      S27 – 使用同步指令。
      S28 – 使用操作对象的指令。
      S29 – 直接访问对象内存指令。如果该标志置0,只能通过对象方法访问对象。
如果S28是0,则该位也必须是0。
      S30 – 在0会话中使用MVRUN指令。
      S31 – 保留,必须是0。

5.4   关闭会话
只有已经建立会话连接后节点才能关闭会话连接,关闭会话连接使用SESSION_CLOSE 
指令。断开连接需要执行3次握手。必须保证在无法控制的紧急情况下也能断开连接。该指
令可由任何一方发出。 假定A是建立连接的启动方,,B是连接的另一方。要关闭连接A
必须发出SESSION_CLOSE指令。发出该指令后A可以重新发送原来的指令,这意味着它
取消了关闭连接指令。应答指令(见第6章)不会影响连接的关闭。发出SESSION_CLOSE
指令的节点不再使用超时限制,可以一直等下去。
节点B在收到SESSION_CLOSE指令后发出RSP_P指令响应。如果应答指令中的基本
返回码是0就表示同意关闭连接,否则表示拒绝。在作出肯定性的响应后,节点在30秒内
不能使用连接。如果在这段时间内,没有从节点A收到除了应答指令以外的   
SESSION_ABEND或其他指令,节点B就发出SESSION_ABEND指令并认为该会话连接已
经关闭。
如果收到的SESSION_CLOSE指令作出了肯定答复,节点A就发出SESSION_ABEND
指令,然后就认为该连接已经关闭了。节点A可能要中止关闭连接,为此只要发出一个其
他命令(也可以是NOP)就可以了。这样关闭过程就终止了,会话连接重新切换到工作状
态。
5.4.1   SESSION_CLOSE
指令“关闭会话”(SESSION_CLOSE)启动会话连接的关闭过程,格式如下:
      OPCODE = 15
      PCK = %b01/11
      CHN = 0
      ASK = 0
      EXT = 0/1
      OPR_LENGTH = 0/1
      SESSION_ID – 受方指定的会话标识符。
      操作数:
         2字节:基本终止码
         2字节:附加终止码
      可选的扩展首部:
         _MSG – 任何信息。
可以没有操作数,相当于0退出码。

5.4.2     SESSION_ABEND
指令“中止会话”(SESSION_ABEND)用于无条件结束会话。发出该指令的节点结束
连接双方的数据交换,不等待对方的响应。格式如下:
      OPCODE = 16
      PCK = %b01/11
      CHN = 0
      ASK = 0
      EXT = 0/1
      OPR_LENGTH = 0/1
      SESSION_ID – 受方指定的会话标识符
      操作数:
         2字节:基本终止码
         2字节:附加终止码
      扩选的扩展首部:
         _MSG – 任意信息
可以没有操作数,相当于0退出码。

5.5   终止任务
用户程序正常结束工作完成任务也就完成了,这个过程在后面描述。下面的情况要求不
考虑整个工作的进展而结束任务:节点上没有足够的资源继续任务的执行;结点已经完成了
工作;由于内部原因虚拟机没有受到结束的命令。任务分配的资源可能位于任何一个节点上,
因此任务结束时必须通知所有的节点。结束任务的节点必须异常关闭与参与该项任务的所有
节点之间的会话连接(发出SESSION_ABEND指令)。

5.5.1     TASK_TERMINATE
指令“终止任务”(TASK_TERMINATE)由结束任务的节点向JCP发出,格式如下:
      OPCODE = 17
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0/1
      OPR_LENGTH = 2/3  ;依赖于CTID的长度。
      操作数:
         2字节:基本终止码
         2字节:附加终止码
         4/8 字节: CTID.
      可选的扩展首部:
         _MSG – 任何信息
向JCP发出TASK_TERMINATE指令后,节点向与该任务有关的所有会话连接发出无
条件结束连接指令ABEND_SESSION,人后就认为该任务已经完成了。如果指令
TASK_TERMINATE中的基本返回码是0,表示无须通知其他节点该任务已经结束。如果任
务没有占用动态资源就可能出现这种情况。如果基本返回码不是0,JCP在收到
TASK_TERMINATE指令后,必须通知执行此项工作的其他节点该任务已经结束。JCP负责
通知参与此项工作的所有节点某一任务的结束。

5.5.2     TASK_TERMINATE_INFO
指令“终止任务信息”(TASK_TERMINATE_INFO)用于通知任务的结束,该指令由
JCP向参与工作的其它节点发出,格式如下:
      OPCODE = 18
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0/1
      OPR_LENGTH = 2-5  ;依赖于GTID的长度
      操作数:
         2字节:基本终止码
         2字节:附加终止码
         4-16 字节:终止任务的GTID,JCP根据取自指令TASK_REG的LTID和任
务的传输层地址构造GTID。
      可选的扩展首部:
         _MSG –任何信息
终止码字段的值取自TASK_TERMINATE指令,工作在收到TASK_TERMINATE_INFO
指令后,必须删除(使其无效)与完成任务的节点有关的所有资源引用。

5.6    工作完成
当启动工作的节点上的相应用户程序完成后工作也就完成了,工作的结束由虚拟机主动
提出,此外在工作的生命期结束后或者JCP节点的工作结束后也可以有JCP结束工作。

5.6.1     JOB_COMPLETED
指令“工作完成”(JOB_COMPLETED)由启动工作的节点向JCP发出,,格式如下:
      OPCODE = 19
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0/1
      OPR_LENGTH = 2/3  ;依赖于CTID的长度
      操作数:
         2字节:基本完成码
         2字节:附加完成码
         4/8 字节:工作完成任务的CTID,是工作GJID的一部分。
      可选的扩展首部:
         _MSG – 任何信息
向JCP发出JOB_COMPLETED 指令后,节点向参与该工作的所有会话连接发出无条
件结束连接指令ABEND_SESSION,然后认为该工作已经结束。JCP在收到
JOB_COMPLETED指令后必须通知参与该工作的所有节点工作已经结束,JCP负责通知所
有的节点工作的结束。如果任务节点非正常结束,也可由JCP发出TASK_TERMINATE_INFO 
指令。

5.6.2     JOB_COMPLETED_INFO
指令“工作完成信息”(JOB_COMPLETED_INFO)用于通知工作已经结束,由JCP向
参与工作的其它节点发出,格式如下:
      OPCODE = 20
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0/1 ;
      OPR_LENGTH = 2-5  ;取决于GJID的长度和是否有完成码字段
      操作数
         2字节:基本完成码
         2字节:附加完成码
         4-16字节:所完成工作的GJID
      可选的扩展首部
         _MSG – 任何信息
完成码字段是可选的。完成码字段取自指令JOB_COMPLETED。节点在收到
JOB_COMPLETED_INFO指令后必须作以下处理:
   (1)  关闭与该任务相关的会话连接,关闭时无需发送基本网络指令。
   (2)  非正常结束工作任务并施放任务占用的动态资源。
如果工作生命期结束或者JCP节点工作完成,JCP也可主动发出
JOB_COMPLETED_INFO指令,此时该指令的第一个接收方是启动工作的节点。发出所有
的JOB_COMPLETED_INFO指令后JCP即认为该工作已完成。

5.7   节点的活动控制
UMSP把以某种方式连接在网络中和没有统一控制方式的节点组织在一起。任何时候节
点都可能断开连接或者发生重载,但是其它节点可能对此并不了解。传输连接的中断或者重
新建立并不能作为结点断开或重载的指示器。对传输连接的控制不属于UMSP协议的范围,
该协议甚至没有要求必须存在传输连接。
在紧急结束节点上的个别任务时,还必须执行第5.5.1节所述的处理过程,否则该节点
上的任务必然是非正常结束的。JCP负责执行控制节点激活状态的函数,因此周期性地在JCP
和任务节点之间来回发出状态查询指令TASK_REQ。
如果JCP检测到节点没有处于激活状态,可能要作以下处理:
   (1)  如果启动工作的任务已经完成,则认为该工作已经完成,JCP给所有执行该工
作的其它节点发出JOB_COMPLETED_INFO指令。
   (2) 如果完成的不是启动工作的任务,则JCP给其他所有节点发出
TASK_TERMINATE_INFO指令。
JCP节点的失效在其重新载入后对GJID的使用有一定限制,,可能有以下变化:
   (1)  JCP结点断开连接是正常通过的,它给控制的所有节点都发出了
JOB_COMPLETED_INFO指令,这种情况下重载后可使用任何GJID。
   (2)  JCP节点突然断开连接,没有通知其他节点。这种情况下必须保证重载后,在
该JCP设定的最大失效时间的两倍时间内,新的GJID不能占用失效前使用的GJID。
如果重载的是非JCP节点则没有类似的限制。

5.7.1     _INACTION_TIME
扩展首部“非活动时间”(INACTION_TIME)允许设定非JCP节点的失效时间,格式
如下:
      HEAD_CODE = 2
      HEAD_LENGTH = 1;
      HOB = 1
      DATA 包括:
         2 字节:不活动时间,0到5秒之间,在这个指定时间范围内,JCP将检查
该指令发送方节点的活动状态。
不活动时间至少要大于传输层上最大传输时间的三倍,传输层的排队等待时间不影响超
时条件。
首部_INACTION_TIME可用于以下指令:
   (1)  如果用于TASK_REG指令,必须满足一定的条件——该节点上不能有其他控
制JCP的激活任务。如果值为0就表示不进行检查,如果不含该首部则表示不活动时间必
须由JCP设定。
   (2)  如果指令TASK_REG指定的值不适合JCP,该首部还可用于TASK_REJECT。
   (3)  如果指令TASK_REG没有包含这个首部,还可用于TASK_CONFIRM。
如果JCP受到带有该首部的TASK_REG指令,必须检查发送该指令的节点是否存在激
活的任务(如果有的话就表示这个节点是重新载入的)。如果存在这样的任务,则必须按照
第5.6.2节所述的过程结束任务,只有完成这些处理后才能发出TASK_CONFIRM指令。

5.7.2     STATE_REQ
指令“状态查询”(STATE_REQ)由JCP发给其他节点上确定的任务,格式如下:
      OPCODE = 21
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0
      OPR_LENGTH = 1/2  ;依赖于LTID的长度。
      操作数:
         4/8字节:指令受方节点指定的LTID。
指令STATE_REQ 在定义任务时发出,但是还与节点有关系。如果在不活动时间间隔
内节点和JCP之间没有发送该指令则发出该指令。发出最后一条STATE_REQ指令后激活的
任务不影响对激活状态的控制。作为对STATE_REQ的响应发送TASK_STATE指令。在等
待响应时,超时限制设为一个不活动时隙。超出时间限制后继任务节点已经被切换掉。
如果节点在两个不活动时隙的时间范围内没有从JCP收到任何指令,即认为JCP已经
完成工作。这种情况下,节点按照已经收到JOB_COMPLETED_INFO指令(见5.6.2节)
进行处理。节点也可以选择检查是否工作已经完成。对于JCP而言,如果没有活动任务与
给定的节点相关,则不对该节点执行激活控制。

5.7.3     TASK_STATE
指令“任务状态”(TASK_STATE)有特定的任务节点向JCP发出,作为对STATE_REQ
指令的响应,格式如下:
      OPCODE = 22
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0
      OPR_LENGTH = 1/2/3  ;取决于CTID的长度
      操作数:
         1字节:任务状态码,取值和相应的含义如下:
            %x01 – 任务处于激活状态并且会话连接也处于激活状态。
            %x02 – 任务激活但是没有会话连接。
            %x03 – 任务激活但是没有会话连接而且在该节点上没有分配资源。
            %x04 – 任务已完成。
         1/3 字节:保留。如果OPR_LENGTH = 1则该字段长1字节否则长3字节,
JCP不得检查给字段的值,该字段在发送时置0。
         2/4/8字节:与取自指令STATE_REQ的LTID相关的CTID。
如果OPR_LENGTH = 1,前一保留字段的长度是1字节,CTID占用2字节。否则保留
字段的长度为3字节,CTID的长度不小于4字节。

5.7.4     NODE_RELOAD
指令“节点重入”(NODE_RELOAD)由JCP作为对STATE_REQ指令的负响应发出,
格式如下:
      OPCODE = 23
      PCK = %b00
      CHN = 0
      ASK = 0
      EXT = 0
      OPR_LENGTH = 1/2  ;取决于LTID的长度。
      操作数:
         4/8字节:取自指令STATE_REQ的LTID。
指令RELOAD_NODE表明,在那个节点上由给定JCP和LTID确定的任务不存在了,
收到该指令后,JCP必须作如下处理:
   (1)  对于在发送倒数第二个STATE_REQ指令之前启动的节点上的所有任务发送
STATE_REQ 指令。
   (2)  在发出最后一个STATE_REQ指令(收到的是否定响应)之后等待一个不活动
时间。
   (3)  对于在最后和倒数第二个STATE_REQ指令(不包括前面的一条中的指令)之
间启动的节点上的所有任务发送STATE_REQ指令。
对于STATE_REQ指令,无论响应是肯定的(TASK_STATE)还是否定的
(RELOAD_NODE)都必须明确答复。

5.8    不使用会话连接的工作方式
协议提供了节点之间不通过建立会话连接交换数据的工作方式,这种方式下工作和任务
不需要初始化,也不是用JCP。不通过连接传输的指令格式与通过会话连接传输的指令完全
对应,区别仅仅在于字段SESSION_ID的值为0或者PCK = %b00。支持无连接工作方式的
节点必须有能够缺省执行不通过连接传输指令的虚拟机。事实上,这些指令在虚拟机的所谓
0会话(0任务))框架下执行。此类虚拟机的内存地址空间无需建立连接也能访问。
SESSION_ID = 0并且REQ_ID = 0的SESSION_INIT指令允许指定其0会话参数或者
请求受方的0会话参数。如果收到该指令的节点要提供需求文档,可以发送
SESSION_ACCEPT指令。否则也发送同样的SESSION_INIT指令,其中的SESSION_ID和 
REQ_ID也是0。实际上这样的会话初始工作不会间连接,不过是通知一下而已。0会话中
的数据交换可以根本不必考虑它。
采用无连接的工作方式有以下限制:1)必须发送整个链,除非整个链都放在一个传输
层的分组内;2)不能请求分配内存或者创建对象(除非使用MVRUN指令)。创建的对象
不从属于特定的工作,在创建对象的工作完成之后也不自动释放内存;3)因为结点随时可
能重入,因此函数参数和返值中不能包含指针,否则可能造成指针无效或者指向其它的地址。
协议无法对这些条件的满足与否进行检查,因此实现是完全依赖于虚拟机。
无连接的工作方式可用于以下系统:1)没有操作系统的简单设备;2)执行大量请求的
服务器上(无连接的工作方式占用的资源较少);3)要求响应快但请求少的系统(保持连接
可能降低响应的速度)。

6  虚拟机之间交换的指令
用于在逊尼基之间交换的指令的操作码在128-233之间,根据操作数字段的不同,同一
操作码可以有不同的指令格式。整个的指令格式由操作码和OPR_LENGTH共同决定。如果
指令首部中的ASK=1,则相应必有REQ_ID字段。REQ_ID用作响应标识符,其值由虚拟
机指定,同样该指令的响应也是虚拟机构造的。对于虚拟机之间交换的指令,协议不检查其
响应也不处理REQ_ID字段。用于应答的指令包括:RSP、DATA、RETURN、ADDRESS、
OBJECT和PROC_NUM。ASK=1的响应指令中的REQ_ID字段值取自原指令。响应指令不
需要应答。
如果满足以下条件,虚拟机之间交换的指令可以通过UDP发送:1)ASK=0;2)指令
包含在一个UDP报文内。
对于虚拟机之间交换的指令,在UMSP传输层上不使用超时限制和重复发送。就是说
如果输出队列非常长,那么优先级较低的指令发送的时间可能很长。因此值由虚拟机才完全
了解传输局的类型,也值由虚拟机才能确定什么时候传输超时。另外,传输层协议需使用超
时限制。可能有多个虚拟机连接到节点上的协议中。虚拟机可以同时执行多个工作,每个工
作都有自己的内存空间。协议根据SESSION_ID字段值确定收到的指令要传递给那个虚拟
机和工作。
本地内存地址保存在指令内一个长为2/4/8字节的字段内。如果指令中的内存地址长度
与节点定义的内存地址长度不同,可能有以下几种情况:1)如果节点的内存地址长24位,
则放在指令的4字节字段的后面3个字节中,高位字节置0;2)如果指令假定内存地址长
度不小于4字节,则用后面的两个字节保存地址,前两个字节置0;3)如果指令是链成员,
而其内存地址长度小于节点所定义的长度则认为使用的是偏移地址,如果没有为这条链指定
基地址,则指令就是错误的。4)如果指令不是链成员,而其内存地址长度小于节点所定义
的长度则认为使用的是缩略地址,但是在其前面必须有足够的0字节占位以保证能够分析出
完整地址的长度;5)除此之外的情形都认为是指令错误。
完整的128位内存地址需要写入16字节长的操作数字段中,使用完整128位地址的原
因是节点上的存储控制子系统所需要的附加信息可以保存在FREE字段中(参见2.1节)。
如果完整地址字段中的FREE部分是0,建议在操作数种使用本地地址。操作数字段有一个
长度值,这是一个32位整数。为了边界对齐,可以在后面添加0字节。在格式描述中没有
涉及到的指令首部字段参照第3章中的说明使用。
传输控制指令JUMP、CALL、CALL_BNUM和CALL_BNAME可以包含发送方虚拟机
的信息。如果指令中包含发送方虚拟机的类型和版本,那么调用参数是按照发送方虚拟机的
格式构造的,否则调用参数就是按照受方虚拟机的格式定义的。代码总是与特定的虚拟机相
关的。协议的所有指令都是用二进制数据,因此没有提供格式转操作。

6.1  数据读/写指令
6.1.1   REQ_DATA
指令“请求数据”(REQ_DATA)用于从远程节点上请求数据,本协议定义了两种格式
的REQ_DATA指令(长度字段分别是2和4字节),格式如下:
      OPCODE = 130/131      ;分别对应长度字段是2和4的两种格式
      OPR_LENGTH = 1/2/3/5  ;取决于地址长度。
      操作数:
         2/4 字节:长度字段,请求数据的字节数。
         2/4/8/16 字节:请求数据的内存地址。
接收方以包含请求数据的DATA指令作为响应,如果不能提供需要的数据则发回基本
返回码非0的RSP指令响应。

6.1.2   DATA
指令“数据”(DATA)用于响应REQ_DATA和OBJ_REQ_DATA指令,格式如下:
      OPCODE = 132
      OPR_LENGTH = 0 - 65535  ;依赖于操作数的直接数据长度
      操作数:
         0 – 262140字节:直接数据,如果OPR_LENGTH = 0则无。
      扩展首部:
         _DATA – 包含直接数据,,如果OPR_LENGTH <> 0则无。
如果数据长度超出了操作数字段的最大允许长度就使用扩展首部,数据不能同时在操作
数和扩展首部中传输。为了保证数据以4字节对齐边界可以在尾部填充1到3个0字节。

6.1.3   WRITE
指令“写数据”(WRITE)用于向远程节点写入数据,格式如下:
      OPCODE = 133/134/135/136  ;对应于长为2/4/8/16字节的内存地址。
      OPR_LENGTH = 1 - 65535   ;取决于直接数据的长度。
      操作数:
         2/4/8/16 字节:数据写入的内存地址
         0 - 262136 字节:写入的直接数据
      扩展首部:
         _DATA – 包含直接数据,只有在操作数字段没有数据时才使用。
如果地址长为2字节则数据也必须是2字节。在其他情况下,地址长度不能小与4字节,
数据必须4的倍数。数据不能同时在操作数字段和扩展首部同时发送。WRITE的应答指令
是RSP,如果正常写入则基本返回码为0。

6.1.4   WRITE_EXT
指令“扩展写数据”(WRITE_EXT)用于向远程节点写入数据,数据可以是从1到262132
的任何字节,格式如下:
      OPCODE = 137
      OPR_LENGTH = 3 - 65535  ;拒绝于直接数据的长度 。
      操作数:
         1字节:必须是0。
         3 字节:写入数据的长度,不能是0。
         4 - 262132 字节:写入的直接数据,数据长必须是4的倍数。
         4/8/16 字节:数据写入的内存地址。
为了保证数据以4字节对齐边界,可以在数据尾部填充1到3个0字节。WRITE_EXT
的响应指令是RSP,正常写入的基本返回码为0。

6.2  比较指令
6.2.1   CMP
指令“比较”(CMP)用于比较二进制数据,格式如下:
      OPCODE = 138/139/140/141  ;对应于2/4/8/16字节的地址长度。
      OPR_LENGTH = 1 - 65535   ;取决于直接数据的长度。
      操作数:
         2/4/8/16字节:比较数据的内存地址。
         2 – 262136字节:比较的直接数据。
         _DATA – 包含直接数据,只有在操作数字段没有数据时才使用。
如果地址长为2字节则数据也必须是2字节。在其他情况下,地址长度不能小与4字节,
数据必须4的倍数。

6.2.2   CMP_EXT
指令“扩展比较”(CMP_EXT)用于比较二进制数据。数据的长度可以从1到262132
字节之间的任意长度,指令格式如下:
      OPCODE = 142
      OPR_LENGTH = 3 - 65535  ; Depends on length of the immediate data
                                and the address.
      操作数:
         1字节:必须是0。
         3 字节:比较数据的长度,不能是0。
         4 - 262132 字节:比较的直接数据,数据长必须是4的倍数。
         4/8/16 字节:比较数据的内存地址。
为了保证数据以4字节对齐边界,可以在数据尾部填充1到3个0字节。WRITE_EXT
的响应指令是RSP,正常写入的基本返回码为0。

6.2.3  对比较指令的应答
指令RSP用于响应CMP、CMP_EXT和OBJ_CMP (参见后述)。如果比较完成则基
本返回码为0,如果地址所指内存中的数据小于操作数字段中的数据则附加返回码为-1;如
果两者相等则附加返回码为0;否则是1。如果无法比较则RSP指令的基本返回码不能是0。

6.3  控制传输指令
6.3.1   JUMP, CALL
“无条件跳转”(JUMP)和“子程序调用”(CALL)指令具有相同的格式,只是操作
码不同,其格式如下:
      OPCODE = 143/144  ;分别对应于不含/包含虚拟机信息的JUMP指令。
               145/146   ;分别对应于不含/包含虚拟机信息的CALL指令。
      OPR_LENGTH = 2 - 65535  ;取决于是否带有虚拟机信息以及地址和参数长度。
      操作数:
         2 字节:发送方的虚拟机类型,如果OPCODE=143/145则无该字段。
         2字节:发送方的虚拟机版本号,如果OPCODE=143/145则无该字段。
         4/8/16 字节:需要传输控制的内存地址。
         2字节:调用参数字段的32位字个数。
         4 – 262134字节:调用参数的直接数据。
控制传输指令的接收方作如下处理:1)检查内存地址,如果地址错误则返回RSP作为
负响应,在这个阶段也可能要检查参数的正确性;2)如果内存地址和参数都正确,对JUMP
指令立即返回正响应的RSP,发送方收到后即认为跳转指令已经执行;3)对于CALL指令
则发出RETURN指令响应,该指令可以包含返回值。如果CALL指令创建的一个线程出现
例外,则返回基本返回码非0的RSP代替RETURN。

6.3.2   RETURN
指令“返回控制”(RETURN)用于从指令CALL、MVRUN、CALL_BNUM和 
CALL_BNAME(见后述)返回控制,格式如下:
      OPCODE = 147
      OPR_LENGTH = 0 - 65535  ;拒绝于直接数的长度。
      操作数:
         0 – 262140字节:从子程序返回的直接数据。
如果不需要返回值,RETURN指令就没有操作数字段,数据格式与原指令相同(发送
方或接收方的虚拟机格式)。

6.4  内存控制指令
UMSP提供了分别存储代码和数据的方法,但是协议不能检查地址操作的正确性。代码
和的值都是用普通的地址空间,对内存的控制完全依赖于虚拟机。

6.4.1   MEM_ALLOC
指令“为数据分配内存”(MEM_ALLOC)用于在数据段中分配内存,格式如下:
      OPCODE = 148
      OPR_LENGTH = 1
      操作数:
         4字节:请求内存的字节数
如果成功分配则以ADDRESS指令响应,否则已基本返回码非0的RSP指令应答。返
回的地址可用于协议的读写、比较或同步指令。

6.4.2   MVCODE
指令“移动代码”(MVCODE用于把执行代码移动到其它节点上,格式如下:
      OPCODE = 149
      OPR_LENGTH = 1 - 65535  ;取决于代码字段的长度。
      操作数:
         2字节:受方的虚拟机类型
         2字节:受方的虚拟机版本号
         0-262136 字节:保存可执行代码
      扩展首部:
         _DATA –保存执行代码,只有操作数字段不含代码时才使用。
代码总是与特定类型的虚拟机相关的。代码字段对于协议来说是透明的,它由发送方的
虚拟机创建并且包含接收方虚拟机所有必要的信息,代码不能同时在操作数字段和扩展首部
同时发送。如果代码移动成功则发出ADDRESS指令响应,否则以基本返回码非0的RSP
指令应答。MVCODE指令传输的代码可以通过JUMP或CALL执行

6.4.3   ADDRESS
指令“内存地址”(ADDRESS)用于响应MEM_ALLOC和MVCODE指令,格式如下:
      OPCODE = 150
      OPR_LENGTH = 1/2/4 ;取决于地址长度
      操作数:
         4/8/16 字节:分配的内存地址
对于指令MEM_ALLOC,返回的地址时所分配的数据区的第一个字节的地址。对于
MVCODE指令,返回的地址由代码相关的虚拟机定义

6.4.4   FREE
通过指令MEM_ALLOC和MVCODE分配的内存必须手工释放,为此提供了“释放内
存”(FREE)指令,格式如下:
      OPCODE = 151
      OPR_LENGTH = 1/2/4 ;取决于地址长度
      操作数
         4/8/16 字节:内存地址
虚拟机在节点任务完成后必须自动释放这段内存。

6.4.5   MVRUN
指令“移动并执行”(MOVRUN)用于同时完成代码移动和执行任务,格式如下:
      OPCODE = 152
      OPR_LENGTH = 1 - 65535  ;取决于代码字段长度
      操作数:
         2字节:接收方的虚拟机类型
         2字节:接收方的虚拟机版本号
         4 - 262136 字节:可执行代码
      扩展首部:
         _DATA – 可执行代码,只有操作数字段不含代码时使用。
可执行代码是包含二进制代码的缓冲区,它对于协议是透明的。该字段的格式由虚拟机
定义,并且必须包含受方虚拟机的载入程序所需要的信息,包括调用参数。代码不能同时在
操作数字段和扩展首部中发送。对MOVRUN指令响应类似于CALL指令的响应,不必释
放该指令所含代码占用的内存,内存由虚拟机负责回收。

6.5  其它指令
6.5.1   SYN
指令“同步”(SYN)用于数据交换的单个消息,格式如下:
      OPCODE = 153/154/155  ;对应4/8/16字节的地址。
      OPR_LENGTH = 2 – 65535 ;取决于数据长度。
      操作数:
         4/8/16字节:要跟踪的数据的内存地址。
         2 – 131068字节:初始数据,长度必须是偶数字节。
         2 - 131068 字节:用于比较的掩码,与初始数据等长。
跟踪数据由第一个操作数指定的地址确定,这些数据首先与第二个操作数指定的初始数
据比较,如果数据不同则认为已经被改变了。通过第三个操作数可以设置比较用的掩码,如
果验码的某一位是1就表示必须跟踪相应数据位的变化。对该指令的响应可以是:1)如果
本地内存地址不正确,则返回基本返回码非0的RSP响应;2)如果数据没有变化则不作应
答;3)如果数据已经改变则是用DATA返回跟踪数据的新值。

6.5.2   NOP
指令“空操作”(NOP)的格式如下:
      OPCODE = 156
      OPR_LENGTH = 0 - 65535
      操作数:
         0 - 262140 字节:封装的数据
      扩展首部:
         任何扩展首部。
该指令可用于:1)如果在某一会话中没有发送其它的指令可以使用NOP传送控制用的
扩展首部;2)封装分段指令和事务,带有特定过程建立的标志(见第7章)。

6.6  操作对象
本协议中有一组指令是对协议RPC[6]的扩展,与RPC不同的是,UMSP允许直接访问
远程节点上的内存地址,也可以在参数或返值中传递对象指针。UMSP对象使用4字节的数
字标识,分为4部分:
        I -> %x00000000 - 1FFFFFFF   用于标准对象。
       II -> %x20000000 - 3FFFFFFF   用于用户对象。
      III -> %x30000000 - 4FFFFFFF   自由使用。
       IV -> %x50000000 - DFFFFFFF   用于临时对象
        V -> %xE0000000 - FFFFFFFF   保留。
第一类对象必须是标准定义的,而且其接口规范是公布的,本协议不支持标准对象的私
有接口或者为描述的接口。第二类对象必须经过注册,但其接口规范不一定要公布,这些标
识符在为了避免不同厂商的系统可能会造成冲突的情况。第三类标识符可以自由使用,通过
它们访问的对象既可以动态创建也可以静态创建,接口也不作限制。这三类对象对于所有的
节点工作包括0会话的工作都是通用的。按照授权,节点上的所有任务都可以访问它们的接
口。第四类标识符用于在某一工作框架内动态建立的对象。这些对象占用与工作相对隔离的
内存空间,对这些对象的访问仅限于特定的工作,0会话工作不能访问此类对象。
本协议允许把对象数据的访问看作是对连续内存区域的访问,对象内存可以与节点上的
普通本地内存交叉。处理对象数据的治理使用偏移地址字段,计算规则与本地内存的偏移地
址相同。UMSP定义的节点内存地址长度限制了对象的最大尺寸。在本节中定义的指令可以
访问的内存范围是节点内存空间的极限大小2^96字节。
除了标识符数字,对象还有2字节的版本号和2字节的实现(realization)。本协议要求
某个对象版本的所有实现必须保持向上兼容。标准对象发布的新实现只需包括增加的接口。
如果对于指令的发送方,对象的实现没有用或者是不可知的,那么指令中的版本号字段和实
现字段都可以是0或者只有实现字段是0。但是不允许版本号是0而实现字段不是0。

6.6.1  读写对象数据
6.6.1.1  OBJ_REQ_DATA
指令“请求对象数据”(OBJ_REQ_DATA)用于从远程节点上读取对象数据,格式如下
      OPCODE = 192/193   ;对应与2/4字节的长度字段
      OPR_LENGTH = 3/4/5  ;取决于偏移字段的长度
      操作数:
         4字节:对象标识符
         2字节:对象的版本号
         2字节:对象的实现
         2/4字节:请求数据的字节数
         2/4/8字节:请求数据的偏移地址(从对象的起始地址开始)。
如果长度字段是2字节则偏移字段也必须是2字节,否则长度字段和偏移字段都不能少
于4字节。该指令的响应指令是带有请求数据的DATA指令,如果无法提供数据则以基本
返回码非0的RSP指令应答。

6.6.1.2  OBJ_WRITE
指令“写对象数据”(OBJ_WRITE)用于向对象写入数据,格式如下:
      OPCODE = 194/195/196   ;对应于2/4/8字节的偏移字段
      OPR_LENGTH = 3 - 65535  ;取决于数据长度
      操作数:
         4字节:对象标识符
         2字节:对象版本号
         2字节:对象的实现
         2/4/8字节:数据写入的对象偏移地址
         2 - 262128 字节:要写入的直接数据
      扩展首部:
         _DATA – 包含要写入的直接数据,只有操作数不含写入数据时才使用。
如果长度字段是2字节则偏移字段也必须是2字节,否则偏移字段都不能少于4字节,
数据长度必须是4的倍数。数据不能同时在操作数和扩展首部中发送。指令RSP作为该指
令的响应指令,如果正常写入则基本返回码为0。

6.6.1.3  OBJ_WRITE_EXT
指令“扩展写对象数据”(OBJ_WRITE_EXT)也用于向对象写入数据,数据长度可以
从1到262132字节,格式如下:
      OPCODE = 197
      OPR_LENGTH = 3 – 65535 ;取决于数据长度和地址长度
      操作数:
         4字节:对象标识符
         2字节:对象版本号
         2字节:对象的实现
         1字节:总是0
         3字节:写入数据的字节数,不能是0
         4 - 262124 字节:要写入的直接数据,长度必须是4的倍数
         2/4/8 字节:数据写入的偏移地址
如果写入的数据长度不正好是4的倍数,可以在后面填充1-3个0字节。如果正常写入,
则发送基本返回码为0的RSP响应。

6.6.2  对象数据的比较指令
6.6.2.1  OBJ_DATA_CMP
指令“比较对象数据”(OBJ_DATA_CMP)使用操作数中的立即数与对象数据逐位进行
比较,格式如下:
      OPCODE = 198/199/200  ;对应2/4/8字节的偏移字段
      OPR_LENGTH = 3 – 65535 取决于数据的长度
      操作数:
         4字节:对象标识符
         2字节:对象版本号
         2字节:对象的实现
         2/4/8字节:要比较的对象数据的偏移地址
         2 - 262128 字节:用于比较的直接数据
如果长度字段是2字节则偏移字段也必须是2字节,否则偏移字段都不能少于4字节,
数据长度必须是4的倍数。对该指令的响应参见第6.2.3节。

6.6.2.2  OBJ_DATA_CMP_EXT
指令“扩展比较对象数据”(OBJ_DATA_CMP_EXT)使用操作数中的立即数与对象数
据逐位进行比较,数据长度可以从1到262132字节,格式如下:
      OPCODE = 201
      OPR_LENGTH = 5 - 65535  ;取决于立即数和地址长度
   操作数:
         4字节:对象标识符
         2字节:对象版本号
         2字节:对象的实现
         1字节:总是0
         3字节:比较数据的字节数,不能是0
         4 - 262124 字节:要比较的直接数据,长度必须是4的倍数
         2/4/8 字节:比较数据的偏移地址
如果写入的数据长度不正好是4的倍数,可以在后面填充1-3个0字节。对该指令的响
应参见第6.2.3节。

6.6.3 调用对象方法
6.6.3.1  CALL_BNUM
指令“通过标识符调用对象方法”(CALL_BNUM)通过数字标识符传递对对象方法的
控制,格式如下:
      OPCODE = 202/203  根据指令不含/包含虚拟机信息
      OPR_LENGTH = 4 - 65535 ;取决于是否包含虚拟机信息以及调用参数的长度。
      操作数
         2字节:发送方虚拟机类型,如果OPCODE=202则无该字段
         2字节:发送方虚拟机的版本号,如果OPCODE=202则无该字段
         4字节:对象标识符
         2字节:对象的版本号
         2字节:对象的实现
         4字节:调用的过程号
         4 - 262128 字节:调用参数
该指令的受方的响应方式类似于对CAALL指令的应答(见第6.3.1节)。

6.6.3.2  CALL_BNAME
指令“通过名称调用对象方法”(CALL_BNAME)通过名称标志传递对对象过程的控
制,格式如下:
      OPCODE = 204/205  根据指令不含/包含虚拟机信息
      OPR_LENGTH = 3 - 65535 ;取决于是否包含虚拟机信息以及调用参数的长度。
      操作数
         2字节:发送方虚拟机类型,如果OPCODE=204则无该字段
         2字节:发送方虚拟机的版本号,如果OPCODE=204则无该字段
         4字节:对象标识符
         2字节:对象的版本号
         2字节:对象的实现
         4 - 262128 字节:调用参数
      扩展首部:
         _NAME – 调用的过程名
该指令的受方的响应方式类似于对CAALL指令的应答(见第6.3.1节)。第三和第四类
对象才能有待名称的对象过程,第一和第二类对象的对象过程在传输层上不能有名称,只能
使用数字标识符。

6.6.3.3  GET_NUM_PROC
指令“取得对象过程号”(GET_NUM_PROC)可以对第三和第四类对象通过过程名取
得对象过程号,格式如下:
      OPCODE = 206
      OPR_LENGTH = 2
      操作数:
         4 字节:对象标识符
         2 字节:对象的版本号
         2 字节:对象的实现
      扩展首部
         _NAME –对象过程名
如果成功执行,则返回PROC_NUM指令,否则发送基本返回码非0的RSP。

6.6.3.4  PROC_NUM
指令“过程号”(PROC_NUM)用于相应GET_NUM_PROC指令,格式如下:
      OPCODE = 207
      OPR_LENGTH = 3
      操作数:
         4 字节:对象标识符
         2 字节:对象的版本号
         2 字节:对象的实现
         4 字节:过程号

6.6.4  创建对象
第一和第二类对象(标准对象和用户对象)不能通过UMSP接口在远程节点上创建,
这些对象只能通过虚拟机的API创建。后两类对象可以通过协议指令在远程节点上创建。
一到三类对象(没有与特定的工作关联)的实现非常困难,这是因为不同的工作具有不同的
内存地址空间,必须根据传递它们的工作上下文进行处理。此外,为了释放动态资源,对象
必须跟踪工作结束与否。特殊的要求对这些对象带来了必要的限制,本协议对第四类对象没
有任何限制。在节点上唯一确定一个对象的就是对象的数字标识符(4字节),对于三类和
四类对象还可以指定一个名字,第一和第二类对象在UMSP层上不能有名字。在同一任务
框架内不能由两个对象具有相同的标识符或者名称。

6.6.4.1  NEW, SYS_NEW
指令“新建对象”(NEW)和“新建系统对象”(NEW_SYS)很相似,前者用于第四类
对象,后者用于第三类对象。这两个指令的格式如下:
      OPCODE = 208/209 ;对应于NEW和NEW_SYS.
      OPR_LENGTH = 3
      操作数:
         2字节:受方虚拟机类型
         2字节:受方虚拟机版本号
         2字节:对象版本号
         2字节:对象实现
         4 - 262136 字节:创建对象需要的直接数据。
      扩展首部:
         _DATA – 创建对象需要的直接数据,只有操作数中不含这些数据时才使用。
         _NAME – 可选,对象名。
指令NEW_SYS用于创建任何工作都可以访问的对象,NEW用于创建只能由构造它的
工作才能访问的对象。如果对象成功创建则发送OBJECT指令应答,否则以基本返回码非0
的RSP指令响应。直接数据字段对于协议而言是透明的,它由发送方的虚拟机定义,但是
必须包含受方虚拟机建立对象所需要的信息。数据不能同时在操作数和扩展首部发送。指令
的SESSION_ID字段不能是0。动态对象只能在确定的工作上下文中创建。对象总是建立在
会话连接的虚拟机上。如果对象的版本号和实现为0就表示该对象没有这些值。在对象创建
的同时可以注册其名称,对象名包含在_NAME扩展首部中。由NEW和NEW_SYS创建的
对象必须手工删除。虚拟机必须在任务结束后自动删除该任务创建但没有销毁的动态对象。

6.6.4.2  OBJECT
指令“对象”(OBJECT)用作NEW和NEW_SYS指令的正响应,其格式如下:
      OPCODE = 210
      OPR_LENGTH = 2
      操作数:
         4 字节:对象数字标识符
         2 字节:对象版本号
         2 字节:对象的实现

6.6.4.3  DELETE
指令“删除对象”(DELETE)用于删除NEW或NEW_SYS指令创建的对象,格式如
下:
      OPCODE = 211
      OPR_LENGTH = 1
      操作数:
         4 字节:对象数字标识符
对象只能建立它的工作内删除,使用RSP响应该指令。

6.6.5  对象标识符
对象在节点上注册时,可以分配一个长为4到254字节的名字,名字必须由ASCII字
符组成。以后的版本可以还会定义其它类型的名字。名字是对象数字标识符的同义词,一项
任务中所有活动对象的名字必须是唯一的。因此对于前三类对象,就一个节点上的所有任务
而言其名字都必须是唯一的。协议允许通过对象名取得对象的数字标识符或者通过数字标识
符取得对象名。

6.6.5.1  OBJ_SEEK
指令“查找对象”(OBJ_SEEK)用于通过名字查找对象的数字标识符,格式如下:
      OPCODE = 212
      OPR_LENGTH = 0
      扩展首部:
         _NAME – 要查找的对象名。
如果找到了需要的对象则发送OBKECT指令,否则发送基本返回码非0的ESP指令响
应。指令OBJ_SEEK可以通过UDP广播发送,这种情况下使用的是0会话。为了识别响应
指令可以包含REQ_ID字段。此时只有正响应才必须发出,响应也可使用UDP发送。

6.6.5.2  OBJ_GET_NAME
指令“获取对象名”(OBJ_GET_NAME)用于通过对象的数字标识符取得对象名,格
式如下:
      OPCODE = 213
      OPR_LENGTH = 1
      操作数:
         4 字节:对象数字标识符
如果对象存在,则返回包含扩展首部_NAME的OBJECT指令,否则以基本返回码非0
的RSP指令响应。

7  链
在一个会话连接中发送的指令可以组织成链,链是一组彼此关联的指令。在一个会话中
可以同时传输几条链。链可分为三类:顺序链、事务和分段指令链。如果指令属于某条链则
其CHN属性必须设为1,首部字段CHAIN_NUMBER保存链的编号,INSTR_NUMBER则
表示从0开始该指令在链内的顺序号。链号由协议管理,在一次会话中最多可同时传输65533
个链。链号%x0000和%xFFFF保留给协议使用。一条链最多可包含65535个指令。 如果指
令的链序列号INSTR_NUMBER是0,则应包含一个描述链的扩展首部,每种类型的链都有
自己的初始扩展首部。无论那种类型的链,在链的最后一条指令中都要发送“链结束”扩展
首部_END_CHAIN,该指令的格式如下:
      HEAD_CODE = 6
      HEAD_LENGTH = 0
      HOB = 1
包含该扩展首部的指令在指令首部的CHAIN_NUMBER字段中保存完成的链号。只有
在所有的链都放入一个分组时,连中的指令才能使用UDP传输。

7.1 顺序链(Sequence)
顺序链把互相依赖的指令组织在一起,只有前面的指令已经执行,后续指令才能在虚拟
机上运行。如果当前指令无法执行,给定顺序链中所有其它指令(已经发出和将要发出的)
都被取消。因此计算控制线程可以不必等待收到确认指令而立即发送后序指令。
序列中的第一条指令要包括扩展首部“序列开始” _BEGIN_SQ,其格式如下:
      HEAD_CODE = 3
      HEAD_LENGTH = 0
      HOB = 1
第一条指令的扩展首部CHAIN_NUMBER字段要保存所建立的链的编号,其
INSTR_NUMBER字段值必须是0。顺序链由虚拟机创建,在创建时不需预先知道链的长度,
随时可以结束链,如果需要结束链而又没有需要发送的指令也可使用NOP指令。

7.2 事务(Transaction)
事务把一些可能彼此无关的指令组成在一起,事务指令要么一起执行要么都不执行。事
务可以取消也可以确认执行,但没有规定事务执行后如何取消。如果需要这样做,那么必须
在虚拟机一层上完成,因为事务中可能包含不可取消的指令如控制传输指令。事务由虚拟机
创建,必须事先知道事务的长度,事务的长度决定了事务的传输方式,与第7.4节描述的缓
冲区有关。

7.2.1   _BEGIN_TR
扩展首部“开始事务”(_BEGIN_TR)在第一条事务指令中传送,格式如下:
      HEAD_CODE = 4
      HEAD_LENGTH = 1
      HOB = 1
      DATA – 数据字段的格式如下: 
      +---+---+---+---+---+---+---+---+
      |TRE|TRR|TRS|      Reserve      |
      +---+---+---+---+---+---+---+---+
      |           TIME_TR             |
      +---+---+---+---+---+---+---+---+
其中1)TRE:1位,强制执行标志,该标志只与已经全部传输完成但还没有执行的事
务有关,如果TRE=1,那么该事务必须在超出字段TIME_TR规定的存在时间之前,或者会
话紧急结束之前执行。如果TRE=0,那么一旦超出事务存在时间,就必须取消事务并发出
负响应指令,但是如果会话紧急结束只要取消事务就可以了;2)TRR:1位,发送完成执
行标志。如果TRR=1,那么必须在所有指令发送完成后再一起执行全部指令,此时只有在
收到包含_END_CHAIN扩展首部的指令后才执行事务。如果TRR = 0,则必须发送特殊的
事务指令EXEC_TR通知开始执行事务;3)TRT:1位,专用处理标志,它是为以后的协议
扩展准备的。如果TRT =1,在执行事务之前必须对指令作一些特殊处理,比方说解码,这
些操作可以在另外的指令扩展首部中定义。本文没有定义该标志的这种用法,TRT的值必
须是0;4)保留,必须设为0;5)TIME_TR,1个字节,事务的生存期(必须是2秒的倍
数,最长8分钟)。接收方在收到所有的事务指令后读取这个时间值。值%x00表示事务没
有生存期限制。

7.2.2   EXEC_TR
指令“执行事务”(EXEC_TR)用于通知接受方执行已经传输的事务,格式如下:
      OPCODE = 158
      ASK = 1
      PCK = %b01/10/11
      CHN = 1
      EXT = 0/1
      CHAIN_NUMBER – 执行事务所必需的链号
      INSTR_NUMBER = 0
      OPR_LENGTH = 0

7.2.3   CANCEL_TR
指令“取消事务”(CANCEL_TR)用于取消执行已经传输的事务,格式如下:
      OPCODE = 159
      ASK = 0
      PCK = %b01/10/11
      CHN = 1
      EXT = 0/1
      CHAIN_NUMBER – 取消事务执行所必需的链号
      INSTR_NUMBER = 0
      OPR_LENGTH = 0
被取消的事务所包含的指令被删除并且不可恢复。

7.3 分段指令
UMSP使用的是数据分组大小有限的传输协议,使用分段指令可能有两种原因:指令超
过了传输层最大分组的长度,或者某个分组包含多条指令而最后一个指令无法完整地纳入。
指令分段是由UMSP层决定的。分段指令放在多个NOP指令中,所有这些NOP指令作为
一种特殊的链发送。分段指令的封装算法如下:
   (1)  分段指令的SESSION_ID和REQ_ID字段写在第一条NOP指令中。如果原来
的指令不含REQ_ID字段,那么NOP指令也不得出现该字段。分段指令必然有SESSION_ID
字段。
   (2) 从原来的指令中删除上述字段,但不改变指令首部的其它字段。
   (3) 然后把原来的指令分成适当大小的分段,每个分段都放在一个NOP指令的操作
数中,其他数据不能写入操作数字段。
包含的一个分段的NOP指令还要带有扩展首部“第一分段”_BEGIN_FRG,其格式如
下:
      HEAD_CODE = 5
      HEAD_LENGTH = 0/2 ;取决于链的从属关系
      HOB = 1
      数据:
         2字节:父链编号,分段指令也可以是顺序链或事务链的一部分。
         2字节:在父链中的指令号。
手部_END_CHAIN在包含最后一个分段的NOP指令中传递。

7.4 缓冲
在本文中,缓冲是针对数据的接收而言的,发送缓冲区的使用超出了本协议的范围。如
果指令不属于任何链,那么在传输后直接执行,不需要协议层的缓冲。UMSP-VM接口必须
提供异步指令发送。建议UMSP系统产品能够按照从网络接收的速度处理来自网络的指令。
所有的指令都能在确定并且有限的时间内执行装配,只有控制传输指令是个例外,它必须分
两个阶段处理。首先要检查指令是否正确并进行调度,然后再执行指令。对此必须保证在处
理器时间内协议能够收到各部分,从而能够在稳定的状态下执行。因此节点的过载问题就推
延到虚拟机层和用户程序层,在这些层上可以进行明确的控制。
对于链来讲,协议提供了两种接收缓冲方式:
   (1) 在建立会话连接时双方就缓冲区(窗口)的大小达成一致,窗口必须大于传输
层最大分组的大小。不需与接收方预先协调,发送方总是认为这个缓冲区是可用的。窗口大
小是每个会话连接单独建立的,而且在会话连接的生存期内不能改变。UMSP使用的传输层
协议会通知对方数据的发送。因此,发送方跟踪接收方窗口的剩余大小毫无用处。如果接收
方发现收到的数据超出了窗口大小就会断开连接。
   (2) 对于事务链和分段指令,如果超出了窗口大小,必须经多接收方节点的认可后
才能发送。传送的链的理论极限值是4G字节。
指令“请求缓冲区”(REQ_BUF)用于向虚拟机请求分配缓冲区以便发送事务链或者较
大的分段指令,格式如下:
      OPCODE = 24
      ASK = 1
      PCK = b01/11
      CHN = 0
      EXT = 0/1
      OPR_LENGTH = 1
      操作数:
         4字节:需要的缓冲区字节数,该值等于所有指令(包括子链)的大小之和。
该指令由协议自动形成并使用指令RSP_P作为响应。但是在接收方缓冲区却是由虚拟
机分配的,因为只有虚拟机才拥有任务的完整信息。UMSP和虚拟机的接口比能够实现缓冲
分配的异步请求。
无论能不能把链放入缓冲区,都已使用REQ_BUF指令请求分配会话窗口。必须要考虑
对该指令的应答可能是否定的,但使用“窗口”可以保证发送。收到的子链要占用父链的缓
冲区。与事务链和分段指令不同,顺序链的传输不需要分配缓冲区。如果发送顺序链使用的
是单路连接的TCP,顺序缓冲就是不必要的。但是如果使用的是多路连接TCP,就需要为
乱序指令准备缓冲区。这种情况下需要分配会话缓冲区。
如果事务链的TRR标志为0,即使能够放在一个传输层分组中,也必须等待对方确认
发出的REQ_BUF指令。
对于分段指令和TRR标志为1的事务链,缓冲方式取决于它们的大小:
1) 如果事务链放在传输层的一个分组内,传输时就不需要缓冲;
2) 如果链的长度小于“窗口”尺寸,那么不必请求窗口分配缓冲区也可以传输。此时,
在发送之前缓冲区的空间必须保留起来。如果缓冲区空间不足,就不能开始发送。
这种情况下可以等待窗口释放或者使用缓冲区分配指令REQ_BUF。
长度超出了会话窗口的尺寸,必须使用指令REQ_BUF。

7.5 链的确认
任何类型的链,其REQ_ID字段都在第一条指令中建立,并对整个链起作用。后续指
令包括最后一条指令都不含REQ_ID字段。传送链的传输层协议必须通知数据传输在何时
完成,因为发送方需要知道接受方所分配的会话窗口所剩余的自由空间大小。如果链使用了
预分配的虚拟机缓冲(发出的REQ_BUF命令得到了肯定响应),或者整个链可以放入一个
传输层分组,那么发送方协议无须等待确认。如果序列已经传输,发送方可以通过传输层传
递的确认收到接收方缓冲区自由空间的大小。除非对方能够完全接收,否则分段指令和事务
链不会传送给虚拟机。如果使用了会话窗口,根据传输层的确认消息可以计算占用的缓冲区
空间大小。为了跟踪自由空间的大小,虚拟机必须核对完成的确认信息。对此可采用以下算
法:
1) 为了发送链,REQ_ID字段的值提交给虚拟机,虚拟机保留该字段但使用协议
指定的值代替原来的值;
2) 包含新值的REQ_ID字段在链的第一条指令中发出;
3) 整个链都放在接收方的会话窗口中,链接完成后交给虚拟机去执行,此时链仍
然占用缓冲区空间;
4) 执行后虚拟机通知接受方协议;
5) 协议清空分配的缓冲区;
6) 协议构造并发出确认命令,与其他情况不同的是使用RSP_P指令(不是RSP);
7) 接受方协议在收到确认指令RSP_P后更正接收方缓冲区自由空间大小的记录;
8) 恢复原来的REQ_ID值并通知虚拟机。

7.6 基 - 偏移寻址方式
可以为链中的指令建立内存基地址和相对地址,因此在链指令中可以使用缩减的地址字
段。缩减地址作为基地址的偏移地址使用。
扩展首部“建立内存基地址”(_SET_MBASE)用于建立链的基地址,格式如下:
      HEAD_CODE = 7
      HEAD_LENGTH = 2/4/8   ;取决于地址长度
      HOB = 1
      DATA 包括:
         4/8/16字节:基地址
地址长度是3字节,如果数据字段是4字节,则写入最后三个字节,高位字节置0。对
于地址长度小于2字节的节点不使用基地址-偏移寻址方式。顺序链中基地址的值可能要发
生变化。对于事务链的所有指令,基地址只能在一个指令中设置一次,改变事务链的基地址
是不允许的,会导致拒绝执行事务。

8  扩展首部
这一节描述与特定指令无关的扩展首部,专用扩展首部已经在相应的指令中讲过了。

8.1 _ALIGNMENT
扩展首部“定位调整”(_ALIGNMENT)允许把任何长度必须是4到16字节倍数的扩
展首部或者操作数字段调整为2字节的倍数。协议对该首部的使用没有限制,格式如下:
      HEAD_CODE = 8
      HEAD_LENGTH = 1-7  ;取决于数据字段的长度
      HOB = 0
      DATA包括:
         2 – 14字节:都必须是0
包含该扩展首部的指令说明使用2字节对界的格式,除此之外没有其他含义。

8.2 _MSG
扩展首部“任何消息”(_MSG)用于传递ASCII文本信息。接收方可以任意的顺序处
理该首部,这些消息可以写入日志文件显示在控制台上或者被忽略。该首部的格式如下:
      HEAD_CODE = 9
      HEAD_LENGTH = 1 - 127 ;取决于数据长度
      HOB = 0
      DATA 包括:
         2 - 254 字节:消息文本
一条指令可以包含多个_MSG首部。

8.3 _NAME
扩展首部“名称”(_NAME)用于制定工作名、对象名或者对象过程名,格式如下:
      HEAD_CODE = 10
      HEAD_LENGTH = 1 - 127 ;取决于数据长度
      HOB = 0
      DATA包括:
         2 - 254 字节:ASCII字符组成的名称

8.4 _DATA
扩展首部“数据”(_DATA)用于虚拟机交换指令的数据传输,仅用于数据不能包含在
操作数中时。一条指令中最多可以传递4G字节的数据,格式如下:
      HEAD_CODE = 11
      HEAD_LENGTH = 1 - 2 147 483 647 ;取决于数据长度
      HOB = 1
      DATA 包括:
         2 - 4 294 967 294字节:任何形式的二进制数据。

8.5 _LIFE_TIME
扩展首部“生存期”(_LIFE_TIME)包含一个时间值,格式如下:
      HEAD_CODE = 12
      HEAD_LENGTH = 1/2;取决于数据长度
      HOB = 1
      DATA 包括:
         2/4字节:以1024毫秒为单位的时间值。
首部_LIFE_TIME用于设定把指令发送到接收方虚拟机的时间限制。计算方法如下:1)
在发送方送网传输层的队列中的等待时间要计入,生存期要减去传输层分组信息中的当前等
待时间;2)接收方只对分段指令计算生存期,生存期要减去指令的装配时间。对于非分段
指令则忽略该首部,生存期的值必须传递给虚拟机。3)传输层的传输时间不算,对于分段
指令,只有第一个分段的传输时间不计。
如果顺序链指令中的生存期已经超出,则结束顺序链的传输。在事务链中不能使用生存
期首部。如果是分段指令,则_LIFE_TIME首不只在包含的一个分段的NOP指令中传输,
并从原来的分段指令中删除。如果生存期已经结束而部分分段指令还没有传输完成,则剩下
的部分被清除。指令生存期由发送方的虚拟机指定,必须与数据一起发送给受方虚拟机。如
果超出了生存期,则拒绝该指令的执行并返回负响应(如果ASK=1,否则不予响应)。在多
媒体系统和实时系统中必须使用_LIFE_TIME首部。在接近生存期时,协议可以提高数据传
送的优先级。

9  资源搜索
虚拟机是本协议的标志资源,虚拟机标准化不是UMSP的任务。本协议仅仅提供了一
个透明的环境实现任何类型的数据和代码的传输。对于与本协议连接的虚拟机建立以下特征
值:虚拟机类型和虚拟机版本,取值范围都从1到65534。协议要求任何类型的虚拟机必须
保持向上兼容(版本号高的虚拟机必须能够执行的版本号的虚拟机代码)。
虚拟机类型号分为以下3类:1 – 1023用于标准虚拟机;1024 – 49151用于用户注册的
虚拟机; 49152 – 65534,自由使用(为动态的或私有的虚拟机定义的)。值为%x0000和
%xFFFF的类型号和版本号保留给协议使用。多个不同类型的虚拟机可以组织成一个组。同
一组内的虚拟机必须在共同的本地内存空间中工作,并且具有共同的工作控制子系统。就是
说,如果一项任务中的不同虚拟机代码引用了同一个128位地址,那么必须指向同一个物理
内存单元。如果满足特定条件,来自不同供应商的用户代码(包含属于不同虚拟机的过程)
可以在同一个节点上执行。一个组中的所有虚拟机必须具有不同的类型,一个组最多可以包
含65534个虚拟机。不同节点上的相同组号可能表示不同虚拟机组成的组。
对于节点上每个成组的虚拟机,都指定一个2字节长的组代码。值要由一个会话连接就
不能改变组代码。建议只有在重新配置节点时才修改组代码。组虚拟机像一般虚拟机那样也
需要标志,此时虚拟机类型号设为0,而虚拟机版本则是用组号。对虚拟机组的支持是可选
的,即使不是用虚拟机组也可以执行来自不同供应商的代码。为此,包含不同类型代码的过
程必须在不同的节点上执行。
UMSP提供了虚拟机查找指令,,可用于确定当前在给定节点上与本协议关联的虚拟机
或者成组虚拟机。虚拟机查找指令可以通过TCP或者UDP发送,也可使用广播方式。节点
可以在一开始或者在相应其它虚拟机请求时单独说明自身可用的虚拟机。应答指令也必须使
用相同的传输层协议发送。编号为49152 – 65534的虚拟机或者任何类型的虚拟机组可以使
用名字来标志,编号为1 – 49151的虚拟机在UMSP这一层上不能使用名称标志。

9.1 VM_REQ
指令“虚拟机请求”(VM_REQ)用于检索与某一远程节点连接的虚拟机,格式如下:
      OPCODE = 25
      PCK = %b00
      CHN = 0
      ASK = 0/1
      EXT = 0/1
      OPR_LENGTH = 0 - 65534 ;取决于操作数中虚拟机的个数
      操作数:
         2字节:请求的虚拟机类型,不能是0
         2字节:请求的虚拟机版本号,不能是0, %xFFFF用于请求最新的版本。
         ……
         2字节:请求的虚拟机类型
         2字节:请求的虚拟机版本号
      可选的扩展首部:
         _NAME – 请求的虚拟机或虚拟机组的名称。
如果指令中不含操作数字段,表示请求与节点连接的所有类型的虚拟机。如果操作数中
有一个虚拟机,则表示要查询该虚拟机的信息。如果操作数中包含多个虚拟机,则表示查询
包含所有指定虚拟机的虚拟机组。列出的虚拟机必须按照类型号和版本号递增排列。如果要
查询以无连接方式工作的虚拟机,虚拟机类型和版本号必须设为%xFFFF。首部_NAME 与
操作数的值无关,因此必须单独应答查询。

9.2 VM_NOTIF
指令“虚拟机反馈”(VM_NOTIF)用于说明与某个节点连接的虚拟机或者虚拟机组的
信息,格式如下:
      OPCODE = 26
      PCK = %b00
      CHN = 0
      ASK = 0/1
      EXT = 0/1
      OPR_LENGTH = 1 - 65534  ;取决于操作数中虚拟机的个数
      操作数:
         2字节:使用的传输协议: 
x0100 – 通过2110端口的单路TCP连接
x0101 – 通过2110端口的多路TCP连接
x0102 – 通过2110端口的单路TCP连接,UDP通过端口2110接收
x0103 - 通过2110端口的多路TCP连接,UDP通过端口2110接收
在每个TCP连接中,至少要有一方打开2110端口
         2字节:保留,接受市目前的协议实现不得处理该字段,发送是必须设为0。
         2字节:虚拟机类型号
         2字节:虚拟机版本号
         ……
         2字节:虚拟机类型号
         2字节:虚拟机版本号
      可选的扩展首部:
         _NAME – 指令操作数中指定的虚拟机或虚拟机组的名字。
如果需要说明多个虚拟机或虚拟机组的信息,就需要构造多条指令。同样如果节点提供
了多种传输层协议,也必须为每种协议单独发送一条信息指令。如果该指令用于应答
VM_REQ请求,可以包含字段ASK = 1和REQ_ID,字段值从请求指令取得。如果查询的
是虚拟机组,那么指令中就应有多个虚拟机,其中的一个虚拟机的类型必须设为0而版本则
设为虚拟机组号,其他的虚拟机则必须定义组结构,列出的虚拟机的类型和版本必须按递增
排列。包含在VM_NOTIF指令中的传输协议可以与发送本指令所使用的协议不同。

10 安全性问题
本文档描述了完成一开始所提出的目标任务——直接访问远程节点的内存——的最基
本的功能。为了降低协议最初的复杂性,本文中没有涉及安全性问题的探讨。给出本文所述
的部分主要是为了以后的扩展。在下面的叙述中使用了3个节点,A和B时交换数据的节
点,G是工作控制点JCP。
对付嗅探器、电子欺骗和偷窃:
      (1) 可以使用TCP/IP所规定的方法
      (2)可以创建一种特殊处理的链,这种链需要在链的第一条指令中传递扩展首部,
指明要进行的特殊处理。链中的指令可以封装在NOP指令中。对指令序列完整性或者加密
的控制可以用这种方式实现。
对付第三者(man-in-the-middle):预防措施基于这样一个事实,即节点A – B、A – G
和B – G之间的路径不会发生交叉,因此通过组织附加的管理数据流就可以识别这一类攻
击。但是如果某条路径要通过网关,这种保护措施的有效性就降低了。
身份验证:本协议是基于集中控制模式工作的,允许采用各种不同的验证方案。验证参
数可以通过扩展首部发送,建立会话连接最多可以包含8次握手,因此可以方便地选择验证
方法。验证可以在三对节点之间实现:A – B、A – G和B – G。任何两对节点的验证都可以
组合使用,节点G可专门用于身份验证。
防范拒绝服务:协议指令的计算载入都是确定的,因此可以设想节点能够按照从网络接
收指令的速度执行,造成过载的的原因只能是CALL和JUMP指令。虚拟机必须解决这个
问题,它完全了解所执行的用户任务,可以决定分配的资源数量,问题的一方面在于低优先
级通信服务失败
对程序架构层的保护:可能由于连接的不对称结构,协议允许创建任何结构的应用程序。
大体可以分为三类:1)执行终端功能的客户端和C/S技术,这类系统的安全性完全由服务
器定义,这类结构的安全性是最高的;2)客户端从服务器装入活动代码,从客户端来看这
是安全性最差的结构。。在服务器端并没有特殊的保护要求。3)客户端在服务器上执行代码,
从客户端来看是安全的结构,但是必须加强服务器保护。这种结构的性能与客户端装载活动
码的结构没有不同。如果考虑到服务器是专门配置的,这种结构最合适。
上述技术可以结合使用。

11 文中使用的缩略语
   API    应用程序接口。
   CTID   JCP为每个工作任务指定的控制任务标识符,其长度等于JCP节点的本地
内存地址的长度。
   GJID   为每项工作分配的全局工作标识符,与JCP节点的128位内存地址格式相
同,工作中的第一项任务的CTID中用于替换本地内存地址。
   GTID   为每项任务分配的全局任务标识符,与节点上的1228位内存地址格式相
同,其中的本地内存地址在LTID中被替换。
   JCP    工作控制点,控制工作的节点。
   LTID   为节点上的每项活动任务分配的本地任务标识符,LTID的长度等于节点上
的本地内存地址长度。
   VM     虚拟机。

12 参考
   [1]  Bradner, S., "The Internet Standards Process -- Revision 3", BCP
        9, RFC 2026, October 1996.

   [2]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
        Levels", RFC 2119, March 1997.

   [3]  Crocker, D., and  P. Overell.  "Augmented BNF for Syntax
        Specifications: ABNF", RFC 2234, November 1997.

   [4]  Postel, J., "Transmission Control Protocol - DARPA Internet
        Program Protocol Specification", STD 7, RFC 793, September 1981.

   [5]  Postel, J., "User Datagram Protocol", STD 6, RFC 768, August
        1980.

   [6]  Srinivasan, R., "RPC: Remote Procedure Call Protocol
        Specification Version 2", RFC 1831, August 1995.

13 作者地址
   Alexander Y. Bogdanov

   NKO "ORS"
   22, Smolnaya St.
   Moscow, Russia 125445
   RU

   Phone: +7 901 732 9760
   EMail: a_bogdanov@iname.ru

14  版权声明
   Copyright (C) The Internet Society (2000).  All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implementation may be prepared, copied, published
   and distributed, in whole or in part, without restriction of any
   kind, provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Internet organizations, except as needed for the purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be
   followed, or as required to translate it into languages other than
   English.

   The limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.

   This document and the information contained herein is provided on an
   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, 
INCLUDING
   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE 
INFORMATION
   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES 
OF
   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement

   Funding for the RFC Editor function is currently provided by the
   Internet Society.

RFC3018——Unified Memory Space Protocol Specification                     统一内存空间协议规范


1
RFC文档中文翻译计划