脚本
char *fr(char *filename){
longupfile ; //定义文件句柄
intcount ; //定于文件长度
intnFileLen; //定义文件长度
char*buffer;
upfile= fopen(filename,"rb"); //以只读方式打开二进制文件,将upfile指向该文件
fseek(upfile,0,2); //将文件指针移动到文件尾
nFileLen= ftell(upfile); //获得文件尾到文件头的偏移字节数,即文件所包含字节数
fseek(upfile,0,0); // 将文件指针移动到文件头
lr_output_message("nFileLen:%d",nFileLen); //打印文件字节数
buffer= (char*)malloc(nFileLen); //分配长度为nfilelen的内存块
count= fread(buffer, sizeof(char),nFileLen, upfile); //将upfile指向的文件所包含字节数的所有数据项读入到buffer中,并返回数据项的字节数,及文件长度
lr_output_message("count:%d",count); //打印读入文件的字节数
lr_save_int(count,"fbuff"); //将文件长度赋值给fbuff
lr_save_int(count-1,"fcurr"); //将文件长度-1赋值给fcurr
returnbuffer; //返回读取的文件
}
vuser_init()
{
lr_save_string(fr("E:\\FS\\testfile\\55.txt"),"fdata");//将读取的文件存到fdata变量中
return0;
}
Action()
{
/*上传文件*/
lr_think_time(3);
lr_start_transaction("hdupfile");
web_add_header("Content-Disposition","p_w_upload;filename=\"testdata.rar\"");
web_add_header("X-Content-Range","bytes0-{fcurr}/{fbuff}");
web_add_header("Session-ID","{userid}");
web_add_header("Content-Type", "application/octet-stream");
web_custom_request("hdup",
"URL=http://10.255.0.149/upload?userId={userid}&bigmd5={userid}&taskId={userid}&offset=0",
"Method=POST",
"Resource=0",
"Referer=",
"Mode=HTML",
"Body={fdata}",
LAST);
lr_end_transaction("hdupfile",LR_AUTO);
return 0;
}
vuser_end()
{
return0;
}
知识点:
C语言读写文件
1. Fopen:
作用: 第一个参数是指向一个文件,如果当前文件不存在,系统会创建这个文件名。第二个参数是对这个文件进行的操作。例如,只读,读写,写等。
Fopen函数原型:
文件指针名=fopen(文件名,使用文件方式)
其中:
文件指针名:必须被指明为FILe类型的指针变量
文件名:被打开文件的文件名,是字符串常量或字符串数组
使用文件方式:是指文件的类型和操作文件的方式
例如:在当前目录打开文件file a,只运行进行读操作,并时fp指向该文件
FILE *fp;
fp=("file a","r");
使用文件的方式共有12种,下面给出了它们的符号和意义。
“rt” :只读打开一个文本文件,只允许读数据
“wt”: 只写打开或建立一个文本文件,只允许写数据
“at”:追加打开一个文本文件,并在文件末尾写数据
“rb”:只读打开一个二进制文件,只允许读数据
“wb”:只写打开或建立一个二进制文件,只允许写数据
“ab”:追加打开一个二进制文件,并在文件末尾写数据
“rt+”:读写打开一个文本文件,允许读和写
“wt+”:读写打开或建立一个文本文件,允许读写
“at+”:读写打开一个文本文件,允许读,或在文件末追加数据
“rb+”:读写打开一个二进制文件,允许读和写
“wb+”:读写打开或建立一个二进制文件,允许读和写
“ab+”:读写打开一个二进制文件,允许读,或在文件末追加数据
把一个文本文件读入内存时,要将ASCII码转换成二进制码,而把文件以文本方式写入磁盘时,也要把二进制码转换成ASCII码,因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。
2. Fseek函数
作用:用于二进制方式打开的文件,移动文件读写指针位置,通常文件打开后,读写位置按先后顺序.但有时你想变动读写位置,例如重新从某处起,再读一次.
Fseek函数原型:int fseek(FILE *stream,long offset,int origin)
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,取值为:SEEK_CUR、SEEK_END 或SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
简言之:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。
3. Ftell函数
Ftell函数原型:long int ftell ( FILE * stream );
作用:用于获得文件位置指针当前位置相对于文件首的偏移字节数。在随机方式取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。调用ftell函数就能非常方便地确定文件位置
利用ftell函数也能方便地知道文件的长度,如:
Fsekk(fp,0,2)//将fp文件指针移动到文件结尾
Len=ftell(fp) //获得从文件结尾到文件首的偏移字节数,该字节数相当于文件所含字节数
4. Malloc函数
函数原型:extern void *malloc(unsignedint num_bytes);
malloc的语法是:指针名=(数据类型*)malloc(长度),
作用:分配长度为num_bytes字节的内存块 说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 当内存不再使用时,应使用free()函数将内存块释放。
5. fread函数和fwrite函数
功能:用来读写一个数据块。
函数原型:
Fread(buffer,size,count,fp)
Fwrite(buffer,size,count,fp)
说明:
(1)buffer:是一个指针,对fread来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址。
(2)size:要读写的字节数;
(3)count:要进行读写多少个size字节的数据项;
(4)fp:文件型指针。
LR函数
1. lr_save_int(intvalue,const char * param_name)
功能,转换整型为字符串型,并将字符串值存到参数中。
2. lr_save_string(const char *param_value, const char *param_name)
功能:将指定以Null结束的字符串赋值给参数
3. web_add_header(constchar * Head, const char * Content)
功能:对于下一个web request,指定请求头
4. web_custom_request(constchar *RequestName, <List of Attributes>, [EXTRARES, <List of ResourceAttributes>,] LAST );
返回值:
返回LR_PASS(0)代表成功,LR_FAIL(1)代表失败。
功能:允许使用任何方法和请求体创建自定义的HTTP请求。默认情况下,当VuGen无法使用其他函数解释用户请求时,会生成此函数。
所有的Web Vusers ,运行在HTTP模式或者Wireless Session Protocol (WSP) 回放模式下的WAPVusers都支持web_custom_request函数。
参数:
RequestName:步骤的名称,VuGen中树形视图中显示的名称。
List of Attribute:支持的属性有以下几种:
URL:页面地址。
Method:页面的提交方式,POST或GET。
TargetFrame:包含当前链接或资源的frame的名称。
EncType:编码类型。比如,text/html, 在请求头里被指定为的content-type的值。如果在消息头里指定了content-tpye,但是该content-tpye不匹配body会导致服务器端的错误。因此建议不要修改录制得到的enctype。
任何对于“EncType”的指定都会覆盖web_add_[auto_]header函数指定的Content-Type。当指定了“EncType=” (空值)时,不会产生“Content-Type” 请求头。当省略了“EncType”时,任何一个web_add_[auto_]header函数都会起作用。如果既没有指定EncType也没有web_add_[auto_]header函数,且“Method=POST”,“application/x-www-form-urlencoded”会做为默认值来使用。其他情况下,不会产生Content-Type请求头。
仅仅当Recording Options--Recording --HTML-based script-- Recordwithin the current script step选项被选中时,List of Resource Attributes才会被插入到代码中。
RecContentType:录制脚本时响应头的内容类型。例如text/html、 application/x-javascript等。当没有设置Resource属性时,用它来确定目标URL是否是可记录的资源。此属性包含主要的和次要的资源。最频繁使用的类型是 text、application、p_w_picpath。次要的类型根据资源不同变化很多。例如:"RecContentType=text/html":表示html文本。"RecContentType=application/msword":表示当前使用的是Msword。
Referer:当前页面关联的页面。如果已经显式指定了url的地址,此项可以省略。
Body:请求体。
Body:表示规则的,可打印的字符串。无法表示空字节。所有的字符都以一个反斜杠表示。注意:在旧的脚本中,可以看见不可打印的字符在请求体中以16进制方式进行编码。(例如 “\\x5c”),在这种情况下,必须使用“Binary=1”来标识。空字节使用"file://0.0.0.0/"来表示。相反,新脚本则会把把请求体分开放在不同的参数中("Body=...","BodyBinary=...", Body=...")。
BodyBinary :表示二进制代码。不可打印的字符在请求体中以16进制方式file://xhh/进行编码。在这里HH 表示十六进制值。空字节使用"file://0.0.0.0/"来表示。
BodyUnicode:美国英语,特指拉丁 UTF-16LE(little-endian)编码。这种编码方式会在在每个字符末尾附加一个0字节,以便使字符更可读。但是在VuGen中实际的参数把所有的0字节都去掉的。但是在发送给Web 服务器之前, web_custom_request函数会重新添加0字节的。对于不可打印的字符,使用单反斜杠表示,无法表示空字节。
注意:如果请求体大于100K,会使用一个变量来代替Body参数。变量是在 lrw_custom_body.h中定义的。
RAW BODY:(目前仅适用与web_custom_request函数):请求体是作为指针传递的,此指针指向一串数据。二进制的请求体可以使用BodyBinary 属性来发送(或者使用Body 属性来传递,前提是必须设置"Binary=1" )。无论如何,这种方法需要使用转义字符反斜杠把不可打印的字符转换为ASCII字符。为了能有一种更简便的表现原始数据的方式,Raw Body属性应运而生,可以传递指向二进制数据的指针。
BodyFilePath:作为请求体传送的文件的路径。它不能与下面的属性一起使用:Body,或者其他Body属性或Raw Body属性包括BodyBinary,BodyUnicode, RAW_BODY_START或Binary=1。
Resource: 指示URL是否属于资源。1 是;0 不是。设置了这个参数后,RecContentType参数被忽略。“Resource=1”,意味着当前操作与所在脚本的成功与否关系不大。在下载资源时如果发生错误,是当作警告而不是错误来处理的;URL是否被下载受“Run-Time Setting—BrowserEmulation--Download non-HTML resources” 这个选项的影响。此操作的响应信息是不做为HTML来解析的。“Resource=0”,表明此URL是重要的,不受发送请求(RTS)的影响,在需要时也会解析它。
ResourceByteLimit:在HTTP模式中无法使用,在Concurrent Groups(Vuser脚本中的一个区,此区中的所有函数并发执行)区中也无法使用。仅仅适用于Sockets的回放,WinInet也是不适用的。
Snapshot:快照的文件名,关联时使用。
Mode:两种录制级别HTML、HTTP。
HTML级别:在当前Web界面上录制直观的HTML动作。以一步步的web_url、web_link、 web_p_w_picpath、web_submit_form来录制这些动作。VuGen仅仅录制返回HTML页面的请求,不处理脚本和应用程序。
HTTP级别:VuGen把所有的请求录制为web_url指令,不生成web_link、web_p_w_picpath、web_submit_form这些函数。这种方法更为灵活,但是生成的脚本不够直观。
ExtraResBaseDir:(目前仅适用与web_custom_request函数):根URL,放在EXTRARES组里。它是用来解析相对URL的(译者加:类似于Windows的相对路径和绝对路径)。
URL可以是绝对路径(例如http://weather.abc.com/weather/forecast.jsp?locCode=LFPO),也可以是相对路径(例如“forecast.jsp?locCode=LFPO”)。
真正的URL的下载是通过绝对路径进行的,所以相对URL路径必须使用根路径URL去解析。例如,使用http://weather.abc.com/weather/做为根路径来解析“forecast.jsp?locCode=LFPO”,最后的URL是:http://weather.abc.com/weather/forecast.jsp?locCode=LFPO。如果没有指定“ExtraResBaseDir”,默认的根URL是主页面的URL。
UserAgent:用户代理,它是一个HTTP头的名字,用来标识应用程序,通常是浏览器,它呈现的是用户和服务器的交互。
例如:头信息“User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; WindowsNT 5.0)”识别的是Window NT下的IE浏览器6.0。其他的User-Agent的值用来描述其他的浏览器,或者非浏览器程序。通常,一个应用程序中所有的请求都使用相同的用户代理,录制者作为一个运行时参数来指定(Run-Time Setting—Browser Emulation—UserAgent)。不管怎么说,即使是在一个简单的浏览器进程中,仍有可能会用到直接与服务器交互的非浏览器组件(例如ActiveX控件),通常他们有着不同于浏览器的用户代理属性。指定“UserAgent”表示这是一个非浏览器的请求。指定的字符串被HTTP头“User-Agent:” 使用,在某些情况下,它同时会影响回放脚本时的行为。例如,不使用浏览器缓存,假设指定的URL属于资源等等。
LoadRunner本身不检查指定的字符串与浏览器本身的值是否相同。
Binary:“Binary=1”表示页面请求体中的每一个以file://x/##形式出现的值(在这里“##”代表2个十六进制数字),都会被替换为单字节的十六进制的值。
如果“Binary=0”(默认值),所有的字符序列只是按照字面的值传递。
需要注意双斜杠的用法。在C编译器中双斜杠被解释为单斜杠。如果不需要零字节,单斜杠可以在Binary不等于1的情况下使用(例如,使用\x20代替file://x20/)。如果需要零字节,那么只能使用file://x00/且设置 “Binary=1”,\x00在逻辑上会被截断
ContentEncoding:指定请求体使用指定的方式(gzip或者deflate)进行编码(例如,压缩),相应的“Content-Encoding:” HTTP头会和此请求一起发送。这个参数适用于web_custom_request和web_submit_data。
EXTRARES:表明下面的参数将会是List Of Resource Attributes了。
LAST :结尾的标示符。
List of Resource Attributes
Web页面中的非HTML机制产生了资源列表,包含了Javascript, ActiveX, Java applets andFlash所请求的资源。VuGen's 的Recording 选项中,可以设置把这些资源录制在当前的操作中(默认是此设置)还是作为单独的步骤来录制。