首页 > 代码库 > UDP与TCP数据包的延迟探测系统
UDP与TCP数据包的延迟探测系统
最近需要测试Akamai的几个节点对数据包加速加速效果,下面是win32上面的一个udp、tcp ping的探测程序。
程序参考了http://www.tenouk.com/Winsock/Winsock2example9.html中的代码。
下面是系统的原理图:
由于udp的特殊性,采用在应用层添加seq的方案,保证回包的准确性(经过测试发现,nmap项目的nping探测器由于没有进行回包准确性的验证,导致最后的统计数据错误,朋友们应该注意)。
而tcp本身就是一种数据流而已,它的机制导致了粘包与分包的问题,tcp探测程序则避开了这两个问题。
最终效果图:
win-cmd:
>.\nping.exe -e UDP -c 500 -p 9999 yfdc.org>.\nping.exe -e TCP -c 500 -p 9999 yfdc.org
tcpping
udpping
WIN客户端探测程序:(vs2008,若用其他编译器,小改一下即可)
1 // frping.c 1.4 2 // date : 20150108 3 // yunthanatos@163.com 4 // you are free to use the codes :) 5 6 #include "stdafx.h" 7 #include <Winsock2.h> 8 #include <stdio.h> 9 #include <WinBase.h> 10 #include <windows.h> 11 #include <Mmsystem.h> 12 #include <sys/timeb.h> 13 #include <time.h> 14 15 #pragma comment(lib,"ws2_32.lib") 16 #pragma comment( lib,"winmm.lib" ) 17 18 /// 19 #include "stdafx.h" 20 21 // Client program example 22 #define WIN32_LEAN_AND_MEAN 23 #include <winsock2.h> 24 #include <stdlib.h> 25 #include <stdio.h> 26 #include <string.h> 27 #pragma comment(lib,"ws2_32.lib") 28 29 30 void Usage(char *progname) 31 { 32 fprintf(stderr,"Usage: %s -e [protocol] -n [server name/IP] -p [port_num] -l [iterations] -d [delay_ms] -t [timeout_s] -c [iterations] ip\n", progname); 33 fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n"); 34 fprintf(stderr,"\t- server is the IP address or name of server\n"); 35 fprintf(stderr,"\t- port_num is the port to listen on\n"); 36 fprintf(stderr,"\t- iterations is the number of loops to execute.\n"); 37 fprintf(stderr,"\t- (-l by itself makes client run in an infinite loop,\n"); 38 fprintf(stderr,"\t- Hit Ctrl-C to terminate it)\n"); 39 fprintf(stderr,"\t- The defaults are TCP , localhost and 2007\n"); 40 WSACleanup(); 41 exit(1); 42 } 43 /* 44 int _tmain(int argc, _TCHAR* argv[]) 45 { 46 return 0; 47 }*/ 48 49 50 int _tmain(int argc, char **argv) 51 { 52 char Buffer[128]; 53 54 // default to localhost 55 char *server_name= "localhost"; 56 unsigned short port = 1080; 57 int retval, loopflag = 0; 58 int i, loopcount, maxloop=50; 59 unsigned int addr; 60 int socket_type = SOCK_STREAM;//SOCK_DGRAM; 61 struct sockaddr_in server; 62 struct hostent *hp; 63 WSADATA wsaData; 64 SOCKET conn_socket; 65 66 // 67 char rcvBuffer[128]; 68 int timestamp_post; 69 int timestamp_pre; 70 int delay_ms=500; 71 int timeout_s=1000; 72 int err; 73 int loss_counter=0; 74 int probe_counter=0; 75 int minrttms=10000000; 76 int maxrttms=0; 77 int sumrttms=0; 78 int deltarttms; 79 char * nonopt=NULL; 80 float float_a,float_b; 81 //socket_type==SOCK_DGRAM)?("UDP"):("TCP"),server_name,port,maxloop,delay_ms,timeout_s 82 83 if (argc >1) 84 { 85 for(i=1; i<argc; i++) 86 { 87 if ((argv[i][0] == ‘-‘) || (argv[i][0] == ‘/‘)) 88 { 89 switch(tolower(argv[i][1])) 90 { 91 case ‘e‘: 92 if (!stricmp(argv[i+1], "TCP")) 93 socket_type = SOCK_STREAM; 94 else if (!stricmp(argv[i+1], "UDP")) 95 socket_type = SOCK_DGRAM; 96 else 97 Usage(argv[0]); 98 i++; 99 break;100 case ‘n‘:101 server_name = argv[++i];102 break;103 case ‘p‘:104 port = atoi(argv[++i]);105 break;106 case ‘l‘:107 loopflag =1;108 if (argv[i+1]) {109 if (argv[i+1][0] != ‘-‘)110 maxloop = atoi(argv[i+1]);111 }112 else113 maxloop = -1;114 i++;115 break;116 case ‘d‘:117 delay_ms = atoi(argv[++i]);118 break;119 case ‘t‘:120 timeout_s = atoi(argv[++i]);121 break;122 case ‘c‘:123 loopflag =1;124 if (argv[i+1]) {125 if (argv[i+1][0] != ‘-‘)126 maxloop = atoi(argv[i+1]);127 }128 else129 maxloop = -1;130 i++;131 break;132 case ‘-‘: // ignore options --133 if(argv[i][2]==‘d‘)134 i++;135 break;136 default:137 Usage(argv[0]);138 break;139 }140 }141 else {142 //Usage(argv[0]);143 nonopt=argv[i];144 //printf("nonopt:%s\n",nonopt);145 }146 }147 }148 if(nonopt!=NULL) {149 server_name=nonopt;150 }151 152 //fprintf(stderr,"Usage: %s -e [protocol] -n [server name/IP] -p [port_num] -l [iterations] -d [delay_ms] -t [timeout_s] -c [iterations] ip\n", progname);153 printf("\n proto_type:%s \n peer_ip_addr:%s\n peer_proto_port:%d\n probe_counts:%d \n probe_interval_ms:%d \n probe_timeout_ms:%d\n\n",154 (socket_type==SOCK_DGRAM)?("UDP"):("TCP"),server_name,port,maxloop,delay_ms,timeout_s); 155 ////// 156 157 if ((retval = WSAStartup(0x202, &wsaData)) != 0)158 {159 fprintf(stderr,"Client: WSAStartup() Error %d\n", retval);160 WSACleanup();161 return -1;162 }163 else164 printf("Client: WSAStartup() is OK.\n");165 166 if (port == 0)167 {168 Usage(argv[0]);169 }170 // Attempt to detect if we should call gethostbyname() or gethostbyaddr()171 /*172 if (isalpha(server_name[0]))173 { // server address is a name174 hp = gethostbyname(server_name);175 }176 else177 { // Convert nnn.nnn address to a usable one178 addr = inet_addr(server_name);179 hp = gethostbyaddr((char *)&addr, 4, AF_INET);180 }181 */182 hp = gethostbyname(server_name);183 if (hp == NULL )184 {185 fprintf(stderr,"Client: Cannot resolve address \"%s\": Error %d\n", server_name, WSAGetLastError());186 WSACleanup();187 exit(1);188 }189 else190 printf("Client: gethostbyaddr() is OK.\n");191 // Copy the resolved information into the sockaddr_in structure192 memset(&server, 0, sizeof(server));193 memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);194 server.sin_family = hp->h_addrtype;195 server.sin_port = htons(port);196 197 198 ///************* make a socket ******************/// 199 conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */200 201 // set time out parameters202 err=setsockopt(conn_socket,SOL_SOCKET,SO_RCVTIMEO,(const char *)&timeout_s,sizeof(timeout_s));203 if(err!=0)204 {205 printf("error:setsockopt \n");206 closesocket(conn_socket);207 WSACleanup();208 return 1;209 } 210 211 if (conn_socket <0 )212 {213 fprintf(stderr,"Client: Error Opening socket: Error %d\n", WSAGetLastError());214 WSACleanup();215 return -1;216 }217 else218 printf("Client: socket() is OK.\n");219 220 // Notice that nothing in this code is specific to whether we221 // are using UDP or TCP.222 // We achieve this by using a simple trick.223 // When connect() is called on a datagram socket, it does not224 // actually establish the connection as a stream (TCP) socket225 // would. Instead, TCP/IP establishes the remote half of the226 // (LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.227 // This enables us to use send() and recv() on datagram sockets,228 // instead of recvfrom() and sendto()229 printf("Client: Client connecting to: %s.\n", hp->h_name);230 if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)231 {232 fprintf(stderr,"Client: connect() Error : %d\n", WSAGetLastError());233 WSACleanup();234 return -1;235 }236 else237 printf("Client: connect() is OK.\n");238 239 // Test sending some string240 loopcount = 0;241 242 ///**********FSM: START************/// 243 probe_counter=0;244 unsigned char seq=1;245 unsigned char * ptr;246 247 while(1)248 {249 ///**********FSM: Send New Sequence UDP Packet************/// 250 // single byte : 2^8=256251 //wsprintf((LPSTR)Buffer,(LPSTR)"%d", loopcount);252 Buffer[0]=seq;253 loopcount++;254 //// timestamp255 timestamp_pre=timeGetTime();256 //printf("-->%d\n",timeGetTime());257 retval = 258 send(conn_socket, Buffer, 1, 0);//send only one probe packet259 probe_counter++;260 if (retval == SOCKET_ERROR)261 {262 fprintf(stderr,"Client: send(): Error %d.\n", WSAGetLastError());263 closesocket(conn_socket);264 WSACleanup();265 goto STATISTICS;266 return -1;267 }268 //else269 // printf("Client: send() is OK.\n");270 271 272 RECV:273 ///**********FSM: recv************/// 274 memset(rcvBuffer,0,128);275 retval = recv(conn_socket, rcvBuffer,1, 0);276 //// timestamp277 timestamp_post=timeGetTime();278 279 if(retval == SOCKET_ERROR)280 {281 ///**********FSM: connection timeout************///282 fprintf(stderr,"Client: recv() : Connection timed out ------------------------> %d \n", WSAGetLastError());283 loss_counter++;284 goto LOOP_END_BEGIN;285 //closesocket(conn_socket);286 //WSACleanup();287 //return -1;288 }289 else 290 { 291 ///**********FSM: Wrong Seq Packet************///292 rcvBuffer[retval]=0;293 /*294 if( atoi(rcvBuffer)!=(loopcount-1) ) {295 printf("<%s>\n",rcvBuffer);296 goto RECV;297 }*/298 ptr=(unsigned char *)rcvBuffer;299 if( (*ptr)!=seq ) {300 printf("<%d>\n",rcvBuffer[0]);301 goto RECV;302 } 303 304 }305 306 ///**********FSM: Check OK :) ************///307 printf("Client: Sent data \"%d\"\n", Buffer[0]);308 printf("Client: recv() is OK.\n");309 if(retval>0) {310 printf("----------------------------> %d\n",timestamp_post-timestamp_pre);311 deltarttms=timestamp_post-timestamp_pre;312 sumrttms=sumrttms+deltarttms;313 if(maxrttms<deltarttms) maxrttms=deltarttms;314 if(minrttms>deltarttms) minrttms=deltarttms;315 //if(deltarttms==0) deltarttms=1;316 317 }318 // We are not likely to see this with UDP, since there is no319 // ‘connection‘ established.320 if (retval == 0)321 {322 printf("Client: Server closed connection.\n");323 closesocket(conn_socket);324 WSACleanup();325 goto STATISTICS;326 return -1;327 }328 printf("Client: Received %d bytes, data \"%d\" from server.\n", retval, Buffer[0]);329 330 LOOP_END_BEGIN:331 if (!loopflag)332 {333 printf("Client: Terminating connection...\n");334 break;335 }336 else337 {338 if ((loopcount >= maxloop) && (maxloop >0))339 break;340 }341 Sleep(delay_ms);342 seq++;343 if(seq==0) seq=1;344 }345 346 STATISTICS:347 // printf("\nsumrttms:%d,maxrttms:%d,minrttms:%d,loss_counter:%d,probe_counter:%d\n",sumrttms,maxrttms,minrttms,loss_counter,probe_counter);348 // printf("mean:%d,better-mean:%d\n",(sumrttms)/(probe_counter-loss_counter),(probe_counter>(loss_counter+2))?((sumrttms-maxrttms-minrttms)/(probe_counter-loss_counter-2)):((sumrttms)/(probe_counter-loss_counter))); 349 float_a=loss_counter;350 float_b=probe_counter;351 // printf("packet loss rate: %.2f%%\n\n\n",float_a*100/float_b);352 353 closesocket(conn_socket);354 WSACleanup();355 356 if((probe_counter!=0)&&(probe_counter!=loss_counter))357 {358 printf("mean:%d.000,better-mean:%d.000\n\n",(sumrttms)/(probe_counter-loss_counter),(probe_counter>(loss_counter+2))?((sumrttms-maxrttms-minrttms)/(probe_counter-loss_counter-2)):((sumrttms)/(probe_counter-loss_counter))); 359 printf("\nMax rtt: %d.000ms | Min rtt: %d.000ms | Avg rtt: %d.000ms\n",maxrttms,minrttms,(probe_counter>(loss_counter+2))?((sumrttms-maxrttms-minrttms)/(probe_counter-loss_counter-2)):((sumrttms)/(probe_counter-loss_counter)));360 printf("Raw packets sent: %d | Rcvd: %d | Lost: %d (%.2f%%)\n",probe_counter,probe_counter-loss_counter,loss_counter,float_a*100/float_b);361 }362 else if(probe_counter>0)363 {364 printf("\nMax rtt: N/Ams | Min rtt: N/Ams | Avg rtt: N/Ams\n");365 printf("Raw packets sent: %d | Rcvd: 0 | Lost: %d (100%%)\n",probe_counter,probe_counter);366 printf("Error \n");367 }368 else {369 printf("\nMax rtt: N/Ams | Min rtt: N/Ams | Avg rtt: N/Ams\n");370 printf("Raw packets sent: N/A | Rcvd: N/A | Lost: %d (N/A%%)\n");371 printf("Error \n");372 }373 374 return 0;375 }
TCP Multithread Echo Server(On GNU/Linux Platform)
1 //multi_thread_server.c 2 // gcc -o multi_thread_server multi_thread_server.c -lpthread 3 4 // date : 20150108 5 // yunthanatos@163.com 6 // you are free to use the codes :) 7 8 9 #include <netinet/in.h> // for sockaddr_in 10 #include <sys/types.h> // for socket 11 #include <sys/socket.h> // for socket 12 #include <stdio.h> // for printf 13 #include <stdlib.h> // for exit 14 #include <string.h> // for bzero 15 #include <pthread.h> 16 #include <sys/errno.h> // for errno 17 18 #define LENGTH_OF_LISTEN_QUEUE 512 19 #define BUFFER_SIZE 128 20 21 void * talk_to_client(void *data) 22 { 23 int new_server_socket = (int)data; 24 char buffer[BUFFER_SIZE]; 25 int length ; 26 int max_times=600; 27 28 //echo back 29 while(max_times--) { 30 bzero(buffer,BUFFER_SIZE); 31 length = recv(new_server_socket,buffer,BUFFER_SIZE-2,0); 32 if(length==-1||length==0) 33 break; 34 buffer[length]=0; 35 send(new_server_socket,buffer,strlen(buffer),0); 36 } 37 //printf("disconnect...\n"); 38 close(new_server_socket); 39 pthread_exit(NULL); 40 } 41 42 void Usage(char *progname) { 43 fprintf(stderr,"Usage: %s -p [port_num]\n", progname); 44 fprintf(stderr,"Usage: nohup %s -p [port_num] &>%s.log &\n",progname,progname); 45 } 46 47 int main(int argc, char **argv) 48 { 49 //ÉèÖÃÒ»¸ösocketµØÖ·½á¹¹server_addr,´ú±í·þÎñÆ÷internetµØÖ·, ¶Ë¿Ú 50 struct sockaddr_in server_addr; 51 bzero(&server_addr,sizeof(server_addr)); //°ÑÒ»¶ÎÄÚ´æÇøµÄÄÚÈÝÈ«²¿ÉèÖÃΪ0 52 server_addr.sin_family = AF_INET; 53 server_addr.sin_addr.s_addr = htons(INADDR_ANY); 54 55 int port; 56 int i; 57 58 if (argc >1) { 59 for(i=1; i<argc; i++) { 60 if ((argv[i][0] == ‘-‘) || (argv[i][0] == ‘/‘)) { 61 switch(tolower(argv[i][1])) { 62 case ‘p‘: 63 port=atoi(argv[++i]);server_addr.sin_port = htons(port); 64 break; 65 default: 66 Usage(argv[0]); 67 return 1; 68 break; 69 } 70 } 71 } 72 } 73 else { 74 Usage(argv[0]); 75 return 1; 76 } 77 78 //´´½¨ÓÃÓÚinternetµÄÁ÷ÐÒé(TCP)socket,ÓÃserver_socket´ú±í·þÎñÆ÷socket 79 int server_socket = socket(AF_INET,SOCK_STREAM,0); 80 if( server_socket < 0) 81 { 82 fprintf(stderr,"Create Socket Failed!"); 83 exit(1); 84 } 85 86 // set time out parameters 87 /* 88 int timeout_s=1000;//ms 89 int err=setsockopt(server_socket,SOL_SOCKET,SO_RCVTIMEO,(const char *)&timeout_s,sizeof(timeout_s)); 90 if(err!=0) 91 { 92 printf("error:setsockopt \n"); 93 close(server_socket); 94 return 1; 95 } 96 */ 97 98 //°ÑsocketºÍsocketµØÖ·½á¹¹ÁªÏµÆðÀ´ 99 if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))100 {101 fprintf(stderr,"Server Bind Port : %d Failed!",port); 102 close(server_socket);103 exit(1);104 }105 106 //server_socketÓÃÓÚ¼àÌý107 if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )108 {109 fprintf(stderr,"Server Listen Failed!"); 110 close(server_socket);111 exit(1);112 }113 114 struct sockaddr_in client_addr;115 socklen_t length = sizeof(client_addr);116 int new_server_socket;117 unsigned long counter=0;118 119 //time120 char newtime[16] ;121 time_t tm = time(NULL);122 struct tm *t = localtime(&tm);123 124 while(1) 125 {126 new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);127 if ( new_server_socket < 0)128 {129 printf("Server Accept Failed!/n");130 break;131 }132 pthread_t child_thread;133 pthread_attr_t child_thread_attr;134 pthread_attr_init(&child_thread_attr);135 pthread_attr_setdetachstate(&child_thread_attr,PTHREAD_CREATE_DETACHED);136 if( pthread_create(&child_thread,&child_thread_attr,talk_to_client, (void *)new_server_socket) < 0 )137 printf("pthread_create Failed : %s/n",strerror(errno));138 139 counter++;140 141 if((counter%50)==0) {142 strftime(newtime, 16, "%Y%m%d%H%M%S", t);143 printf("current-time:%s total-clients:%lu\n",newtime,counter);144 }145 146 }147 148 close(server_socket);149 150 return 0;151 }
UDP Echo Server(On GNU/Linux Platform)
1 // date : 20150108 2 // yunthanatos@163.com 3 // you are free to use the codes :) 4 5 #include<stdio.h> 6 #include<string.h> 7 #include<unistd.h> 8 #include<sys/types.h> 9 #include<sys/socket.h> 10 #include<stdlib.h> 11 #include<netinet/in.h> 12 #include<arpa/inet.h> 13 #include <time.h> 14 #include <stdio.h> 15 16 #define MAXBUFSIZE 50 17 18 void Usage(char *progname) { 19 fprintf(stderr,"Usage: %s -p [port_num]\n", progname); 20 fprintf(stderr,"Usage: nohup %s -p [port_num] &>%s.log &\n",progname,progname); 21 } 22 23 int main(int argc, char **argv) 24 { 25 int sockfd; 26 struct sockaddr_in server; 27 struct sockaddr_in client; 28 socklen_t addrlen; 29 int num; 30 char buf[MAXBUFSIZE]; 31 unsigned long counter=0; 32 33 //time 34 char newtime[16] ; 35 time_t tm = time(NULL); 36 struct tm *t = localtime(&tm); 37 38 int port; 39 int i; 40 41 if (argc >1) { 42 for(i=1; i<argc; i++) { 43 if ((argv[i][0] == ‘-‘) || (argv[i][0] == ‘/‘)) { 44 switch(tolower(argv[i][1])) { 45 case ‘p‘: 46 port=atoi(argv[++i]); 47 break; 48 default: 49 Usage(argv[0]); 50 return 1; 51 break; 52 } 53 } 54 } 55 } 56 else { 57 Usage(argv[0]); 58 return 1; 59 } 60 61 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 62 { 63 perror("Creatingsocket failed."); 64 exit(1); 65 } 66 67 bzero(&server,sizeof(server)); 68 server.sin_family=AF_INET; 69 server.sin_port=htons(port); 70 server.sin_addr.s_addr= htonl (INADDR_ANY); 71 72 if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1) 73 { 74 perror("Bind()error."); 75 exit(1); 76 } 77 78 addrlen=sizeof(client); 79 80 counter=0; 81 while(1) 82 { 83 84 bzero(buf,MAXBUFSIZE); 85 num =recvfrom(sockfd,buf,MAXBUFSIZE-2,0,(struct sockaddr*)&client,&addrlen); 86 87 if (num < 0) 88 { 89 perror("recvfrom() error\n"); 90 exit(1); 91 } 92 counter++; 93 buf[num] = ‘\0‘; 94 95 sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&client,addrlen); 96 97 //log 98 if((counter%100)==0) { 99 strftime(newtime, 16, "%Y%m%d%H%M%S", t);100 printf("current-time:%s total-clients:%lu\n",newtime,counter);101 }102 }103 close(sockfd); 104 }
UDP与TCP数据包的延迟探测系统
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。