|
我在用LOAD RUNNER7.51测试window socket的时候,一直有一个问题没法解决,
每次我的请求中发送的变量是不一样的,同样返回的数据也有可能是不同的,长度不同,而且也不一定每次都包含固定的字符,我试了lrs_receive ,lrs_receive_ex等等相关的函数,都不能达到效果,后来我在function reference里看到有一个主题,提到了这方面的问题,内容如下:
LoadRunner Function Reference
--------------------------------------------------------------------------------
Variable Socket Lengths
This section describes how to create a script that handles receive socket buffers with variable lengths.
Problem
Several applications work with variable length receive sockets. The application makes two calls to the server: the first call to obtain the buffer length and the second call to retrieve the buffer information. VuGen only makes a single call and handles the entire socket as buffer information, thus ignoring the dynamic behavior of the application.
In the following example, the replay failed because it handled all of the bytes as data:
Call to receive buffer:
lrs_receive("socket0", "buf7", LrsLastArg);
Contents of Receive Buffer:
recv buf7 64
"\x00\x00\x00"
"<"
"0"
"\x06\x02\x01\x04\x02\x01\x00\x16\x01\x00"
"0!"
"\x02\x04\x01\xb5\x18\x9b\x02\x01\x05\x02\x01"
"2"
"\x02\x01\x00\x02\x01\x00\x02\x01\x01\x02\x01\x02\x02\x01\x04\x02\x01\x00\x02\x0\x03"
"0"
"\x0c\x02\x04\x01\x00"
"!"
"\xe8\x02\x04\x80\x00\x10"
"A"
The recording log indicates that two calls were made to the receive buffer by the application. In the first call, four bytes were received. In the second call, 60 bytes were received.
/* recv(): 4 bytes were received from socket 1568 using flags 0 (4 requested) */
(recv_10, 4, 1568)
"\x00\x00\x00"
"<"
/* recv(): 60 bytes were received from socket 1568 using flags 0 (60 requested) */
(recv_11, 60, 1568)
"0"
"\x06\x02\x01\x04\x02\x01\x00\x16\x01\x00"
"0!"
"\x02\x04\x01\xb5\x18\x9b\x02\x01\x05\x02\x01"
"2"
"\x02\x01\x00\x02\x01\x00\x02\x01\x01\x02\x01\x02\x02\x01\x04\x02\x01\x00\x02\x01\x03"
"0"
"\x0c\x02\x04\x01\x00"
"!"
"\xe8\x02\x04\x80\x00\x10"
"A"
Solution
Create a wrapper function, custom_lrs_receive that makes two calls to lrs_receive_ex: the first to get the buffer header (length), and the second to receive all the other bytes in the receive buffer based to the retrieved length. Define the new function and specify its prototype. This wrapper function should also contain a parsing routine that makes any required conversions, for example a Hex string to a number. You can also add a debug function that issues an error message when the function fails. After you define the wrapper function, replace the lrs_receive function from your script with the new function.
#define lrs_receive custom_lrs_receive
int custom_lrs_receive(char *sock_desc, char *buf_desc,void *dummy)
{
int rc;
int buf_len = 4;
char szBytesLength[30], *buf = NULL, *pszError, *pszLastChar;
/* Get first 4 bytes */
rc = lrs_receive_ex(sock_desc, buf_desc,
"NumberOfBytesToRecv=4", LrsLastArg);
if(rc != 0)
{
lr_error_message("receive of 4 bytes failed The error code = %d", rc);
return -1;
} /* Recieve failed */
lrs_get_last_received_buffer(sock_desc, &buf, &buf_len);
if(buf == NULL || buf_len != 4)
{
lr_error_message("receive of %s failed", buf_desc);
if(szTranSaction != NULL)
my_lr_end_transaction(szTranSaction, LR_FAIL);
return -1;
}
/* Compute buffer length */
sprintf(szBytesLength, "NumberOfBytesToRecv=%d",
fiFromHexBinToInt(buf) - 4);
lr_debug_message(LR_MSG_CLASS_FULL_TRACE, "!!!! Bytes length = %s",
szBytesLength);
/* Get The buffer according to the length */
rc = lrs_receive_ex(sock_desc, buf_desc,
szBytesLength, LrsLastArg);
if(rc != 0) /* Receive failed */
return -1;
return 0;
}
/* Parse the header, convert HEX string to base 10.*/
int fiFromHexBinToInt(char *szBuffer)
{
int i, j, iIntValue = 0, iExp = 1;
for( i = 3; i >= 0; i--)
{
iExp = 1;
for(j = 6; j > i*2; j--)
iExp *= 16;
iIntValue += (szBuffer & 0x0000000f) * iExp
+
((szBuffer & 0x000000f0) >> 4) * iExp * 16;
}
return iIntValue;
}
Example
/*********************************************************************
* Created by Mercury Interactive Windows Sockets Recorder
*
* Created on: Thu Nov 12 09:37:54
*********************************************************************/
#include "lrs.h"
/*
szBuffer - length = Fix size 4 bytes.
*/
int fiFromHexBinToInt(char *szBuffer)
{
int i, j, iIntValue = 0, iExp = 1;
for( i = 3; i >= 0; i--)
{
iExp = 1;
for(j = 6; j > i*2; j--)
iExp *= 16;
iIntValue += (szBuffer & 0x0000000f) * iExp
+
((szBuffer & 0x000000f0) >> 4) * iExp * 16;
}
return iIntValue;
}
int custom_lrs_receive(char *sock_desc, char *buf_desc,void *dummy)
{
int rc;
int buf_len = 4;
char szBytesLength[30], *buf = NULL, *pszError, *pszLastChar;
/* Get first 4 bytes */
rc = lrs_receive_ex(sock_desc, buf_desc,
"NumberOfBytesToRecv=4", LrsLastArg);
if(rc != 0)
{
lr_error_message("receive of 4 bytes failed The error code = %d", rc);
return -1;
} /* Recieve failed */
lrs_get_last_received_buffer(sock_desc, &buf, &buf_len);
if(buf == NULL || buf_len != 4)
{
lr_error_message("receive of %s failed", buf_desc);
return -1;
}
/* Compute buffer length */
sprintf(szBytesLength, "NumberOfBytesToRecv=%d",
fiFromHexBinToInt(buf) - 4);
lr_debug_message(LR_MSG_CLASS_FULL_TRACE, "!!!! Bytes length = %s",
szBytesLength);
/* Get The buffer according to the length */
rc = lrs_receive_ex(sock_desc, buf_desc,
szBytesLength, LrsLastArg);
if(rc != 0) /* Recieve failed */
return -1;
return 0;
}
--------------------------------------------------------------------------------
Copyright 2002 Mercury Interactive Corporation
Documentation comments or suggestions?
Please send feedback to documentation@merc-int.com
里面关于fiFromHexBinToInt做法不是很理解是什么意思,我照这个样子试了以后,发现每次取回来返回包的长度是个负数,估计是哪里搞错了。
请大虾指教,接收不定长返回包的有效办法。十分感谢! |
|