loadrunner测试TCP协议服务器性能   .

性能loadrunner测试c

最近对服务器的性能感兴趣,于是开始研究了一阵子loadrunner如何做采用TCP协议交互的服务器的性能测试,对loadrunner不是很熟悉,所以一开始也走了一些弯路,现将学习的过程记录下来,为以后做参考吧。

TCP协议的服务器的性能测试,我想大家都会选择loadrunner的winsocket协议进行测试,我也是采用此种方式。下面将逐一记录如何使用此协议做性能测试。

1.采用DLL文件方式进行测试

由于与服务器连接的客户端的DLL文件我手头有,同时其对应的头文件也有,所以一开始试想的是采用loadrunner调用DLL文件的方式来实现性能测试。因为这种方式简单,不需了解很多loadrunner的winsocket的相关函数,容易上手。下面的代码即是采用DLL文件初步编写的代码:

vuser_init.c

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01.vuser_init()
02.{
03. lrs_startup(257);
04. lr_load_dll("InnoVSSBASClient.dll");
05. lr_load_dll("ole32.dll");
06. return 0;
07.} action.c [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01.#include "lrs.h"
02.#include "def.h"
03.
04.Action()
05.{
06.
07. char* test;
08. long handle;
09. NET_CLIENT_INFO info;
10. int isLogin;
11. NET_CROSS_INFO crossInfo;
12. NET_VEHCILE_PASS_INFO lrPassInfo = {0};
13. NET_VEHCILE_ALARM_INFO lrAlarmInfo = {0};
14. handle = InnoVSSBASClient_Init(NULL,NULL);
15. strcpy(info.clientId,guid_gen());
16. strcpy(info.serverIP,"127.0.0.1");
17. info.serverPort = 9300;
18. strcpy(info.username,"admin");
19. strcpy(info.password,"admin");
20.
21.
22. lr_start_transaction("tran_login_start");
23.
24. isLogin = InnoVSSBASClient_CreateConn(handle,&info);
25. if(isLogin==1){
26. lr_end_transaction("tran_login_start", LR_AUTO);
27. lr_output_message(info.clientId);
28. lr_output_message("登陆成功");
29.
30. //InnoVSSBASClient_SetCallbackFunc(handle,InnoVSSBASClientCallback,1L);
31.
32. lr_start_transaction("tran_addcross_start");
33. strcpy(crossInfo.crossId,lr_eval_string("{crossId}"));
34. InnoVSSBASClient_AddCrossInfo(handle,&crossInfo);
35. lr_end_transaction("tran_addcross_start", LR_AUTO);
36.
37. }else{
38. lr_end_transaction("tran_login_start", LR_FAIL);
39. lr_output_message(info.clientId);
40. lr_output_message("登陆失败");
41. }
42.
43.
44.
45. while(1)
46. {
47. sleep(100);
48. }
49. return 0;
50.} vuser_init中加载了程序所需要的DLL文件,InnoVSSBASClient.dll为与服务器连接的客户端的DLL文件,而ole32.dll为程序中的字符串函数(比如strcpy等)需要加载的DLL文件。 action中则是性能测试的主体代码。本代码一共对两个操作:登录和添加路口信息做了事务监控。 采用DLL文件的方式针对测试简单的顺序的操作很适用,但是本客户端还有个功能是需要处理服务器实时传输的过车等信息的功能,即在测试服务器端功能的时候,还需要模拟出客户端的回调函数的功能,但是在loadrunner中没有找到定义回调函数的方式,于是不得不放弃这种简单的性能测试的方式。在此想向loadrunner的大牛问一下,如何在loadrunner中第一回调函数呢? 上面的方式不能真实的模拟客户端的情况,于是下面会记录采用loadrunner本身的winsocket函数进行测试。 2.采用loadrunner的winsocket函数做测试 我先上源码,然后逐一讲解: def.h //本文件是外部文件,在此用于定义自定义函数 [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01.char* guid_gen(){ //生成GUID方法
02. typedef struct _GUID {
03. unsigned long Data1;
04. unsigned short Data2;
05. unsigned short Data3;
06. unsigned char Data4[8];
07. } GUID;
08. GUID m_guid;
09. char buf[50];
10. char pNameStr[50];
11. CoCreateGuid(&m_guid);
12. // 定义输出格式
13. //sprintf (buf, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", // 大写
14. //sprintf (buf, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",// 小写
15. sprintf (buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",// 小写%08lx-%04x%04x-%02x%02x%02x%02x-%02x%02x%02x%02x
16. m_guid.Data1, m_guid.Data2, m_guid.Data3,
17. m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
18. m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
19. //lr_save_string(buf, paramName);
20. //sprintf(pNameStr,"{%s}",paramName);
21. return lr_eval_string(buf);
22.}
23.
24.char* join(char *s1, char *s2)
25.{
26. char *result = (char*)malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator
27. //in real code you would check for errors in malloc here
28. if (result == NULL) exit (1);
29.
30. strcpy(result, s1);
31. strcat(result, s2);
32.
33. return result;
34.}
35.
36.// 字符串替换函数.
37.// 能替换所有的要替换的字符串,被替换的字符串和替换的字符串不一定一样长.
38.// pInput - 输入字符串.
39.// pOutput - 输出字符串, 要保证足够的空间可以存储替换后的字符串.
40.// pSrc - 要被替换的子字符串, 比如%user%
41.// pDst - 要替换成的字符串, 比如user1
42.// 注意:以上的字符串均要以'\0'结尾.
43.//
44.void Substitute(char *pInput, char *pOutput, char *pSrc, char *pDst)
45.{
46. char *pi, *po, *p;
47. int nSrcLen, nDstLen, nLen;
48.
49. // 指向输入字符串的游动指针.
50. pi = pInput;
51. // 指向输出字符串的游动指针.
52. po = pOutput;
53. // 计算被替换串和替换串的长度.
54. nSrcLen = strlen(pSrc);
55. nDstLen = strlen(pDst);
56.
57. // 查找pi指向字符串中第一次出现替换串的位置,并返回指针(找不到则返回null).
58. p = (char*)strstr(pi, pSrc);
59. if(p)
60. {
61. // 找到.
62. while(p)
63. {
64. // 计算被替换串前边字符串的长度.
65. nLen = (int)(p - pi);
66. // 复制到输出字符串.
67. memcpy(po, pi, nLen);
68. memcpy(po + nLen, pDst, nDstLen);
69. // 跳过被替换串.
70. pi = p + nSrcLen;
71. // 调整指向输出串的指针位置.
72. po = po + nLen + nDstLen;
73. // 继续查找.
74. p = (char*)strstr(pi, pSrc);
75. }
76. // 复制剩余字符串.
77. strcpy(po, pi);
78. }
79. else
80. {
81. // 没有找到则原样复制.
82. strcpy(po, pi);
83. }
84.}
85.
86./* @param char* dest 目标串,也就是替换后的新串
87.* @param const char* src 源字符串,被替换的字符串
88.* @param const char* oldstr 旧的子串,将被替换的子串
89.* @param const char* newstr 新的子串
90.* @param int len 将要被替换的前len个字符*/
91.char *strreplace(char *dest, char *src, const char *oldstr, const char *newstr, size_t len)
92.{
93. //子串位置指针
94. char *needle;
95. //临时内存区
96. char *tmp;
97.
98. //如果串相等,则直接返回
99. lr_output_message("newStr:%s",newstr);
100. if(strcmp(oldstr, newstr)==0)
101. {
102. return src;
103. }
104.
105. //把源串地址赋给指针dest,即让dest和src都指向src的内存区域
106. dest = src;
107. //如果找到子串, 并且子串位置在前len个子串范围内, 则进行替换, 否则直接返回
108. while((needle = (char *) strstr(dest, oldstr)) && (needle -dest <= len))
109. {
110. //分配新的空间: +1 是为了添加串尾的'\0'结束符
111. tmp=(char*)malloc(strlen(dest)+(strlen(newstr)-strlen(oldstr))+1);
112. //把src内的前needle-dest个内存空间的数据,拷贝到arr
113. strncpy(tmp, dest, needle-dest);
114. //标识串结束
115. tmp[needle-dest]='\0';
116. //连接arr和newstr, 即把newstr附在arr尾部, 从而组成新串(或说字符数组)arr
117. strcat(tmp, newstr);
118. //把src中 从oldstr子串位置后的部分和arr连接在一起,组成新串arr
119. strcat(tmp, needle+strlen(oldstr));
120. //把用malloc分配的内存,复制给指针retv
121. dest = (char *)strdup(tmp);
122. //释放malloc分配的内存空间
123. free(tmp);
124. }
125. return dest;
126.} 本文件包含了两种功能的函数:一个是如何生成guid,一个是如何替换字符串中的子串。 action.c [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01./*********************************************************************
02. * Created by Mercury Interactive Windows Sockets Recorder
03. *
04. * Created on: Tue Dec 30 16:04:06
05. *********************************************************************/
06.
07.#include "lrs.h"
08.#include "def.h"
09.
10.Action()
11.{
12. int sendLoginCount=0,sendCrossCount=0;
13. int loginIndex,loginIndex2;
14. char* clientId = guid_gen();
15. char clientId2[100];
16. char* clientId3;
17. int clientIdlen;
18. char* loginSrc = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Parament>\n"
19. " <ClientId>$ClientId</ClientId>\n"
20. " <ServerIP>$IP</ServerIP>\n"
21. " <ServerPort>$Port</ServerPort>\n"
22. " <Username></Username>\n"
23. " <Password></Password>\n"
24. "</Parament>";
25. char* loginStr;
26. int loginStrLen;
27. char* loginStrLenHex;
28. char loginStrLenStr[5];
29. char send_loginHeader[100]="\\x12$Len\\x00\\x010";
30. char* send_loginHeaderf;
31. char send_loginStr[1500]="";
32.
33.
34. //添加路口相关字符串
35. char* crossSrc= "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Parament>\n"
36. " <ClientId>$ClientId</ClientId>\n"
37. " <CrossId>$CrossId</CrossId>\n"
38. "</Parament>";
39. char* send_addCrossHeader = "\\x12$Len\\x00\\x02";
40. char* crossId = lr_eval_string("<db_crossId>");
41. char* crossStr;
42. char send_crossStr[1700];
43. char crossStrLenStr[5];
44. int crossStrLen;
45. char* send_addCrossHeaderf;
46. int crossAddIndex,crossAddIndex2;
47.
48. strcpy(clientId2,lr_eval_string(clientId));
49. clientId3 = clientId;
50.
51.
52. //登陆数据
53. loginStr = strreplace(loginStr,loginSrc,"$ClientId",clientId,strlen(loginSrc));
54. loginStr = strreplace(loginStr,loginStr,"$IP","127.0.0.1",strlen(loginStr));
55. loginStr = strreplace(loginStr,loginStr,"$Port","9300",strlen(loginStr));
56. lr_output_message("loginStr:%s",loginStr);
57.
58. loginStrLen = strlen(loginStr)+1;
59. //lr_output_message("loginStrLen:%d",loginStrLen);
60. //itoa(loginStrLen,loginStrLenStr,16);
61. sprintf(loginStrLenStr, "%X", loginStrLen);
62. //lr_output_message("loginStrLenStr:%s",loginStrLenStr);
63. if(strlen(loginStrLenStr)==2)
64. {
65. char tmpH[5];
66. strcpy(tmpH,loginStrLenStr);
67. strcpy(loginStrLenStr,"\\x00\\x00\\x00\\x");
68. strcat(loginStrLenStr,tmpH);
69. }else{
70. char tmpH[5];
71. char tmpD[5];
72. strcpy(tmpH,loginStrLenStr);
73. strcpy(tmpH+1,"\0");
74. strcpy(tmpD,loginStrLenStr+strlen(loginStrLenStr)-2);
75. strcpy(loginStrLenStr,"\\x00\\x00\\x0");
76. strcat(loginStrLenStr,tmpH);
77. strcat(loginStrLenStr,"\\x");
78. strcat(loginStrLenStr,tmpD);
79. //lr_output_message("tmpH:%s",tmpH);
80. //lr_output_message("tmpD:%s",tmpD);
81. }
82. //lr_output_message("loginStrLenStr:%s",loginStrLenStr);
83.
84. send_loginHeaderf = strreplace(send_loginHeaderf,send_loginHeader,"$Len",loginStrLenStr,strlen(send_loginHeader));
85. //lr_output_message("send_loginHeader:%s",send_loginHeaderf);
86. strcpy(send_loginStr,send_loginHeaderf);
87.
88. //lr_output_message("send_loginStr:%s",send_loginStr);
89.
90. for(loginIndex=0,loginIndex2=strlen(send_loginStr);loginIndex<strlen(loginStr);loginIndex++,loginIndex2++)
91. {
92. char loginHex[5];
93. sprintf(loginHex,"\\x%.2X",loginStr[loginIndex]);
94. //strcat(send_loginBody,loginHex);
95. strcat(send_loginStr+loginIndex2,loginHex);
96. }
97. strcat(send_loginStr+loginIndex2,"\\x0A");
98. lr_output_message("send_loginStr:%s",send_loginStr);
99.
100.
101. //创建TCP连接
102. lr_start_transaction("login");
103. lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=127.0.0.1:1234",LrsLastArg);
104. for(sendLoginCount = 0;sendLoginCount < 10;sendLoginCount++)
105. {
106. //lr_output_message("send_loginStr:%s",send_loginStr);
107. lr_output_message("sendLoginCount:%d",sendLoginCount);
108. lrs_set_send_buffer("socket0",send_loginStr,strlen(send_loginStr));
109. lrs_send("socket0","buf0",LrsLastArg);
110. lrs_receive("socket0", "buf1", LrsLastArg);
111. {
112. char* login_recv;
113. int login_recvlen;
114. int i;
115. lrs_get_last_received_buffer("socket0",&login_recv,&login_recvlen);
116. if(login_recvlen!=0)
117. {
118. lr_end_transaction("login", LR_AUTO);
119. lr_output_message("%s",login_recv+15);
120.
121.
122. //添加路口
123. lr_output_message("clientId3:%s",lr_eval_string(clientId2));
124. crossStr = strreplace(crossStr,crossSrc,"$ClientId",clientId3,strlen(crossSrc));
125. crossStr = strreplace(crossStr,crossStr,"$CrossId",crossId,strlen(crossStr));
126. lr_output_message("crossStr:%s",crossStr);
127. crossStrLen = strlen(crossStr)+1;
128. sprintf(crossStrLenStr,"%X",crossStrLen);
129. if(strlen(crossStrLenStr)==2)
130. {
131. char tmpH[5];
132. strcpy(tmpH,crossStrLenStr);
133. strcpy(crossStrLenStr,"\\x00\\x00\\x00\\x");
134. strcat(crossStrLenStr,tmpH);
135. }else{
136. char tmpH[5];
137. char tmpD[5];
138. strcpy(tmpH,crossStrLenStr);
139. strcpy(tmpH+1,"\0");
140. strcpy(tmpD,crossStrLenStr+strlen(crossStrLenStr)-2);
141. strcpy(crossStrLenStr,"\\x00\\x00\\x0");
142. strcat(crossStrLenStr,tmpH);
143. strcat(crossStrLenStr,"\\x");
144. strcat(crossStrLenStr,tmpD);
145. //lr_output_message("cross_tmpH:%s",tmpH);
146. //lr_output_message("cross_tmpD:%s",tmpD);
147. }
148. //lr_output_message("crossStrLenStr:%s",crossStrLenStr);
149.
150. send_addCrossHeaderf = strreplace(send_addCrossHeaderf,send_addCrossHeader,"$Len",crossStrLenStr,strlen(send_addCrossHeader));
151. //lr_output_message("send_addCrossHeaderf:%s",send_addCrossHeaderf);
152. strcpy(send_crossStr,send_addCrossHeaderf);
153. //lr_output_message("send_crossStr:%s",send_crossStr);
154.
155. for(crossAddIndex=0,crossAddIndex2=strlen(send_crossStr);crossAddIndex<strlen(crossStr);crossAddIndex++,crossAddIndex2++)
156. {
157. char crossHex[5];
158. sprintf(crossHex,"\\x%.2X",crossStr[crossAddIndex]);
159. //strcat(send_loginBody,loginHex);
160. strcat(send_crossStr+crossAddIndex2,crossHex);
161. }
162. strcat(send_crossStr+crossAddIndex2,"\\x0A");
163. lr_output_message("send_crossStr:%s",send_crossStr);
164. //lr_output_message("send_loginStr:%s",send_loginStr);
165.
166. lr_start_transaction("addCross");
167. for(sendCrossCount=0;sendCrossCount<10;sendCrossCount++)
168. {
169. lr_output_message("send_crossStr:%s",send_crossStr);
170. lr_output_message("sendCrossCount:%d",sendCrossCount);
171. lrs_set_send_buffer("socket0",send_crossStr,strlen(send_crossStr));
172. lrs_send("socket0","buf0",LrsLastArg);
173. lrs_receive("socket0","buf1",LrsLastArg);
174.
175. {
176. char* cross_recv;
177. int cross_recvlen;
178. lrs_get_last_received_buffer("socket0",&cross_recv,&cross_recvlen);
179.
180. if(cross_recvlen!=0)
181. {
182. lr_end_transaction("addCross", LR_AUTO);
183. lr_output_message("cross_recv:%s",cross_recv+15);
184. break;
185. }else{
186. //lr_end_transaction("addCross", LR_FAIL);
187. }
188.
189. }
190. }
191. if(sendCrossCount>10)
192. {
193. lr_end_transaction("addCross", LR_FAIL);
194. }
195.
196. break;
197.
198. }else{
199. //lr_end_transaction("login", LR_FAIL);
200. }
201.
202. }
203. }
204.
205.
206. if(sendLoginCount>10)
207. {
208. lr_end_transaction("login", LR_FAIL);
209. }
210.
211. while(1)
212. {
213. char* recv;
214. int recvlen;
215.
216. lrs_receive("socket0","buf3",LrsLastArg);
217. lrs_get_last_received_buffer("socket0",&recv,&recvlen);
218.
219. if(recvlen!=0)
220. {
221. lr_output_message("recv:%s",recv+15);
222. }else{
223.
224. }
225.
226. }
227.
228. lrs_close_socket("socket0");
229.
230. return 0;
231.} 上面代码的具体业务就不介绍了,在此我介绍一下在该片代码中应该注意的地方: 1)本代码模拟了客户端所发的16进制的数据,在此提一下字符、字符串如何转换成loadrunner中的16进制的字符串。 在loadrunner中16进行的字符采用前面加’\x'的方式表示,如16进制0xAB,则在loadrunner中需要表示为'\xAB‘; 整形转为16进制字符串:sprintf(loginStrLenStr, "%X", loginStrLen); 16进制字符串转换为loadrunner中认可的16进制串: [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01.for(loginIndex=0,loginIndex2=strlen(send_loginStr);loginIndex<strlen(loginStr);loginIndex++,loginIndex2++)
02. {
03. char loginHex[5];
04. sprintf(loginHex,"\\x%.2X",loginStr[loginIndex]);
05. //strcat(send_loginBody,loginHex);
06. strcat(send_loginStr+loginIndex2,loginHex);
07. } 本部分使用的是本方法,即将字符串“abcd"的的每个字符逐一转换成loadrunner认可的16进制串(如:字符”a"转换成"\x61“) 该方法是个笨方法,不知在loadrunner中有没有自带的函数做字符串的16进制转换呢? 2)loadrunner做winsocket测试的基本步骤: [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01./*********************************************************************
02. * Created by Mercury Interactive Windows Sockets Recorder
03. *
04. * Created on: Mon Dec 29 09:01:03
05. *********************************************************************/
06.
07.#include "lrs.h"
08.
09.
10.Action()
11.{
12. int i;
13. char *buffer;//定义字符指针
14. int numberOfBytes;//定义int型变量保存长度
15.
16. //这是第一步initializes a socket
17. lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=127.0.0.1:1234",LrsLastArg);
18.
19. lr_start_transaction("send");
20. //这里是第二步,通过建立的socket1将buf1中的数据发送给远端MM-7QL3Z0JYUJN6用户,端口2425
21. lrs_send("socket0", "buf1", LrsLastArg);
22.
23. //输出缓冲区数据大小
24. lrs_send("socket0", buffer, LrsLastArg);
25.
26. //从buf2中接收返回的数据
27. lrs_receive("socket0", "buf2", LrsLastArg);
28.
29. //取得缓冲区数据
30. lrs_get_buffer_by_name("buf2", &buffer, &numberOfBytes);
31. //输出缓冲区数据大小
32. lr_output_message("The buffer's size is: %d/n", numberOfBytes);
33. lr_output_message(buffer);
34.
35. lr_end_transaction("send", LR_AUTO);
36.
37.
38. //第三步关闭释放socket连接
39. lrs_close_socket("socket0");
40.
41. return 0;
42.} 上面的代码的注释很明确了,不过需要注意一点的是,loadrunner中lrs_send中的缓存的buf需要在data.ws中定义,不能是程序中定义的字符串。 data.ws [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
01.;WSRData 2 1
02.
03.send buf0
04.recv buf1 101
05.recv buf2 210
06.recv buf3 300
07.
08.-1 3)对winsocket编程的一些函数的解释 ①lrs_set_send_buffer("socket0",send_loginStr,strlen(send_loginStr)); lrs_set_send_buffer将程序中定义的字符串放入data.ws第一个定义的send bufx中,如上面的data.ws中定义的为buf0,则是将其方式buf0中,不管调用多少次,都是放入到buf0中。 ②lrs_receive("socket0", "buf1", LrsLastArg); lrs_get_last_received_buffer("socket0",&login_recv,&login_recvlen); buf1定义的长度与实际接收的长度不一致没关系,loadrunner只会在输出中输出一个警告信息,但是不会影响实际接收的数据。警告信息为: Mismatch in buffer's length (expected 101 bytes, 222 bytes actually received, difference in 121 bytes)

loadrunner测试TCP协议服务器性能的更多相关文章

  1. TCP协议的性能评测工具 — Tcpdive开源啦

    Github地址:https://github.com/fastos/tcpdive 为什么要开发Tcpdive 在过去的几年里,随着移动互联网的飞速发展,整个基础网络已经发生了翻天覆地的变化. 用户 ...

  2. loadrunner 录制TCP协议脚本操作

    测试TCP协议的项目,涉及到登陆.发送实时数据.指令.登出等,直接写报文工作量太大,所以需要录制报文. 操作方法如下: 1.启动服务端程序 2.使用winsocket协议 3.选择应用程序 4.录制选 ...

  3. Loadrunner测试webservice协议总结

    Loadrunner测试webservice协议总结 一.协议选择 1.打开Virtual user generator,新建脚本,选择webservice协议

  4. Tsung测试Tcp协议的应用或接口

    利用Tsung模拟基于Tcp的业务流程,实属无奈.因ConnectManager部署在linux下,其中,Loadrunner的winsocket因不支持linux platform而无法使用,而Jm ...

  5. Jmeter测试TCP协议

    最近做了个项目是TCP协议传输数据,于是马上想试试JMeter测试TCP. 1首先需要下载第三方的TCP插件包ApacheJMeter_tcp.jar,下载步骤请自行百度. 2.下载完重新配置jmet ...

  6. Nginx均衡TCP协议服务器案例

    Nginx在企业运维中通常用来均衡HTTP协议,例如我们熟知的80.8080.8081等服务.因为大部分的服务都是http请求访问协议,那有时候需要用到TCP协议,如果来实现均衡呢? 默认nginx不 ...

  7. TCP 协议快被淘汰了,UDP 协议才是新世代的未来?

    TCP 协议可以说是今天互联网的基石,作为可靠的传输协议,在今天几乎所有的数据都会通过 TCP 协议传输,然而 TCP 在设计之初没有考虑到现今复杂的网络环境,当你在地铁上或者火车上被断断续续的网络折 ...

  8. Web服务器性能/压力测试工具http_load、webbench、ab、Siege、loadrunner

    回头看看 Web服务器性能/压力测试工具http_load.webbench.ab.Siege.loadrunner

  9. 简单测试nginx1.90做TCP协议负载均衡的功能

    最近工作中需要做TCP层面的负载均衡,以前网站用的反向代理nginx只支持应用层的负载均衡,对于TCP协议是无能为力的,需要使用LVS(linux虚拟服务器). LVS的特点是高性能和极复杂的配置.对 ...

随机推荐

  1. [codeforces/gym/101350/L]维护“凸包”

    题目链接:http://codeforces.com/gym/101350/problems 给定n个墙,每个墙有一个高度,要支持动态修改墙的高度和查询这个“容器”能盛多少水. (队友)观察发现,能盛 ...

  2. POJ 2763 Housewife Wind 纯粹LCA写法(简单无脑)

    Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordina ...

  3. 微服务与devops的文章推荐

    http://www.sohu.com/a/125040520_355140 http://www.csdn.net/article/2015-11-18/2826253 http://www.cnb ...

  4. mysql的select的五子句

    转: http://www.cnblogs.com/billyu/p/5033167.html http://www.cnblogs.com/xiadong90-2015/p/4222965.html ...

  5. bzoj 1221 [HNOI2001] 软件开发 费用流

    [HNOI2001] 软件开发 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1938  Solved: 1118[Submit][Status][D ...

  6. 分别利用并查集,DFS和BFS方法求联通块的数量

    联通块是指给定n个点,输入a,b(1<=a,b<=n),然后将a,b连接,凡是连接在一起的所有数就是一个联通块: 题意:第一行输入n,m,分别表示有n个数,有输入m对连接点,以下将要输入m ...

  7. sudo 的配置详解

    从编写 sudo 配置文件/etc/sudoers开始: sudo的配置文件是/etc/sudoers ,我们可以用他的专用编辑工具visodu ,此工具的好处是在添加规则不太准确时,保存退出时会提示 ...

  8. Oracle raw类型

    RAW(size):长度为size字节的原始二进制数据,size的最大值为2000字节; RAW类型好处:在网络中的计算机之间传输 RAW 数据时,或者使用 Oracle 实用程序将 RAW 数据从一 ...

  9. HDU1164

    //HDU 1164 //输入一个数(1<x<=65535) 转化为素数的乘积() #include "iostream" #include "cstdio& ...

  10. 图论:Prufer编码-Cayley定理

    BZOJ1430:运用Cayley定理解决树的形态统计问题 由Prufer编码可以引申出来一个定理:Cayley 内容是不同的n结点标号的树的数量为n^(n-2) 换一种说法就是一棵无根树,当知道结点 ...