之前在网上找到 socket 函数的说明,但是这两个函数并没有详细介绍,所以根据官方文档整理了一下
接收来自指定长度的缓冲区的数据,主要步骤是先确定长度数据位置,获取到长度数据,然后根据长度数据去获取实际数据。
int lrs_length_receive(char **socket_descriptor*, char **buffer*, int *location_option*,
[char* *locators*], [char* *additional_params*],LrsLastArg );
location_option (定位模式),使用哪种方法进行定位:
lrs_receive功能一样)locator(定位器,跟上一个参数对应),对应上面的参数,对应的 locator 参数有三种组合如下:
Offset=xxx (默认 0),长度,Size=xxx
LB=xxx
RB=xxx
Ordinal= ,偏移量,Offset=xxx
Size=xxx
LB=xxx
Ordinal= 偏移量:Offset=xxx
additional_params(额外参数),主要包括缓冲区长度格式和长度计算相关的其它问题:
Encoding=,编码:0,十六进制(默认),1,十进制Order=,顺序,0,根据客户端(默认),1,根据网络顺序SubtractSize=,是否减去长度,0,不减去本身长度(默认),1,减去本身长度Flags= ,用法不明LrsLastArg,参数结尾标识
成功返回 0,否则返回错误码。
例子 1:
下面的例子用location_option=1的方式来说明,buffer1包含2字节的长度数据(粗体)和实际的数据
首先得到长度数据51之后,lrs_length_receive继续从socket0读取51字节的数据到buffer2,注意这里不需要设置 offset,使用默认值即可。
buffer1
51aaabbccdddeeeeeeeeeeeeeeffffffffffffgggggghhhhhhhi
lrs_create_socket("socket0","TCP", "RemoteHost=bona.mercury.com:7", LrsLastArg);
lrs_send("socket0","buffer1", LrsLastArg);
lrs_length_receive("socket0","buffer2", OffsetSize, "Size=2", LrsLastArg);
这个例子:
2读取前两位长度数据,也就是51,51之后,51字节的数据。例子 2:
这个例子使用location_option=2的定位方式,左边界LLLL,右边界RRRR,序数设置为2(表示以第二个LLLL作为左边界),偏移量设置为27(表示从黑体开始往右偏移27字节),根据右边界RRRR可以判定长度数据为9(黑体),然后函数继续读取右边界后面开始的 9 个字节的数据,在这里为Requested,将数据存入buff4,lrs_receive将剩下的数据存入buffer。
buffer3
12LLLL34*LLLLOOOOOfffffsssssseeeeeTTTTTT9*RRRRRequestedZZZZZZZZZZZZZZZZZZZZ2LLLLAAAAAAAAAAAAAAAAAAAAAAEndBuf
lrs_create_socket("socket0","TCP", "RemoteHost=bona.mercury.com:7", LrsLastArg);
lrs_send("socket0","buffer3", LrsLastArg);
lrs_length_receive("socket0","buffer4", 2, "LB=LLLL", "RB=RRRR","Offset=27", "Ordinal=2", LrsLastArg);
// 获取剩余数据
lrs_receive("socket0","buffer5", LrsLastArg);
这个例子:
LLLL作为左边界,然后偏移量为 27,也就是到了字符串中的TTTTT后面RRRR,所以可以得到表示长度的数据为黑体的9
RRRR之后获取9个字符即为期望的字符,在本例中为Requested
例子 3:
这个例子使用location_option=2的定位方式,设置左边界\\x00\\x00\\x00\\x07,然后根据偏移量设置Offset=7往后便宜7个字节,根据长度设置size=2取出 2 字节的长度数据16,由于设置了SubtractSize=1,所以需要减去本身的长度2(所以实际要获取的长度为16-2=14),所以获取数字16以后的14的字节,在这个例子中为RequestedData,最后用lrs_receive获取剩下的数据。
buffer6
12LLLL34*\x00\x00\x00\x07eTTTTTT16*RequestedDataZZZZZZZZZZZZZZZZZZZZ2LLLLAAAAAAAAAAAAAAAAAEndBuf
lrs_create_socket("socket0","TCP", "RemoteHost=bona.mercury.com:7",
lrs_send("socket0","buffer6", LrsLastArg);
lrs_length_receive("socket0","buffer7", 3, "LB/BIN=\\x00\\x00\\x00\\x07","size=2", "Offset=7", "SubtractSize=0",LrsLastArg);
这个例子:
\\x00\\x00\\x00\\x07,根据偏移量7往右偏移到了TTTTTT
Size=2,所以可以获取到之后的两个字节16,这个表示的我们希望的长度数据SubtractSize=0说明长度16还包含了本身的长度2,所以减去之后,我们感兴趣的长度只有14了。16后的14个字符即可,本例中为RequestedData。函数读取指定长度的数据到buffer,长度数据在数据本身里面,用户必须清楚的知道长度数据的具体位置,并使用location_option和locators两个参数来指定长度数据的具体位置,lrs_length_receive首先得到长度数据,然后根据长度数据读取相应的数据到buffer。
location_option参数说明
lrs_length_receive这时候功能跟lrs_receive一样。但是lrs_set_receive_option设置的选项不影响lrs_length_receive(会影响到lrs_receive)。 LB和RB,读取的数据为紧接着右边界后面的数据(长度为左右边界之间的数据决定),同时Offset和Ordinal可以作为可选参数。LB/BIN和RB/BIN来表示左边界和右边界,如RB/BIN=\\x00\\x00\\x01\\x00\\x00\\x00
Size决定,同时Offset和Ordinal可以作为可选参数。locator 参数: Locator联合起来定位长度数据的位置,如:"LB=LeftLeft ", "Size=1","Offset=18"
location_option=1(OffsetSize)中使用Offset表示从开始到长度数据有多少字节。location_option=2或3(LeftRightBoundaries或者LeftBoundarySize)中Offset表示长度数据在左边界+Offset个字节后面,这在左边界之后不确定内容但是是固定字节数的时候很有用。例如,有一个固定的左边界ABC,之后始终有两个未知的数据,就可以设置LB=ABC和Offset=2 Ordinal 参数
location_option=2或3(LeftRightBoundaries或LeftBoundarySize),它表示长度数据在第几个左边界的后面。例如左边界 ABC 出现了很多次,如果设置 Ordinal=2,则表示长度数据在第二个 ABC 之后。Offset一起使用,先确定了第几个左边界,然后在左边界后面偏移Offset个字节的数据来确定长度。 额外的参数
Order=1,Encoding=1
SubtractSize可以让你从长度数据中减去本身的长度,如长度数据是16,实际计算的时候减去本身长度2,即为14。向流套接字发送指定长度的缓冲区数据
int lrs_length_send(char **socket_descriptor*, char **buffer*, int *location_option*,
[char* *locators*], [char* *additional_params*],LrsLastArg );
lrs_send功能一样)locator(定位器,跟上一个参数对应)对应上面的参数,对应的 locator 参数如下:
Offset=xxx"(默认 0) Size=xxx
LB=xxx
RB=xxx
Ordinal=,偏移量,Offset=xxx
Size=xxx
LB=xxx
Ordinal=,偏移量:Offset=xxx
additional_params(额外参数)缓冲区长度格式和长度计算其它问题:
Encoding=,编码,0,十六进制(默认),1,十进制Order=,顺序,0,根据客户端(默认),1,根据网络顺序SubtractSize=,是否减去长度,0,不减去本身长度(默认),1,减去本身长度Flags= ,用法不明 LrsLastArg 参数结尾标识成功返回 0,否则返回错误码。
在这个例子中,buf6通过socket0发送,数据使用了参数化,NameParameter是一个参数,从一系列的数据中取值。 4是长度数据,但是,随着参数NameParameter变化,长度也在随着变化,比如:David长度应该改为5,Michael长度应该改为7。
buf6
Start Data LBoundary & Offset:4:RBoundary
#include "lrs.h"
Action() {
lrs_create_socket("socket0","TCP","RemoteHost=bonaparte.mercury.co.il:7",LrsLastArg);
lrs_length_send("socket0","buf6",LeftRightBoundaries,"LB=LBoundary","RB=:RBoundary", "Offset=10",LrsLastArg);
lrs_close_socket("socket0");
return 0;
}
通过lrs_length_send可以实现下面的动态发送数据。
===SENT BUFFER (on first iteration) ===
"Start Data LBoundary & Offset:5:RBoundaryDavid"
===SENT BUFFER (on second iteration) ===
"Start Data LBoundary & Offset:7:RBoundaryMichael"
在这个例子中
LBoundary,然后偏移量为10,定位到了Offset:后面的位置:RBoundary,所以中间的部分就是长度数据这个函数大部分参数跟lrs_length_receive相同。
lrs_length_send可以用来发送指定长度的数据,这在发送数据中包含参数化数据的时候很有用,因为每次发送的数据长度不一致,通过函数可以在每次发送数据之前将正确的长度写入到发送数据中去。
长度数据的查找方法跟lrs_length_receive类似,也是通过locator和location_option两个参数来定位。
在调用函数之前,用户必须明确知道长度数据在哪里,函数首先计算长度,然后写入长度规定的字节数到缓冲区发送出去。
socket_descriptor,buffer
这两个参数跟lrs_send完全一致。
location_option(定位模式)
lrs_length_send跟lrs_send完全一致。 Offset规定了从数据开始的偏移量,Size规定了长度数据所占的字节数,Offset和Size参数就可以确定长度数据的具体位置。如Offset=6, Size=4。需要计算长度的数据为长度数据之后的数据。Offset的默认值是 0(从数据最开始算起)LB和RB,需要计算长度的数据为右边界后面的数据。Offset和Ordinal用法同上,不再介绍。/BIN,如RB/BIN=\\x00\\x00\\x01\\x00\\x00\\x00
Size个字节,参数为LB,Size,同时Offset和Ordinal也可以作为可选参数,用法同上。 Locator 参数
关于 Offset 参数的用法,Ordinal 的用法,以及附加参数的用法同函数 lrs_length_receive