Udp类:对UDP套接字进行封装
udp.h
1 // udp.h对UDP套接字进行封装 2 #ifndef __UDP_H__ 3 #define __UDP_H__ 4 5 class Udp 6 { 7 private: 8 int sock; //套接字描述符 9 public:10 int Open(char *errbuff);11 void Close();12 int Bind(char* addr, unsigned short port, char* errbuff);13 int Recv(char* buff, int len, unsigned int &nip, 14 unsigned short &nport, char* errbuff);15 int Send(char* buff, int len, unsigned int nip,16 unsigned short nport, char *errbuff);17 18 int Getfd(){ return sock;} 19 Udp();20 ~Udp();21 };22 23 #endif
udp.cpp
1 // udp.cpp 2 #include3 #include 4 #include 5 /*以上三个头文件为网络编程所必须*/ 6 7 #include 8 #include 9 #include 10 #include 11 12 #include "udp.h" 13 #include "defs.h" 14 15 16 Udp::Udp() 17 { 18 sock = -1; 19 } 20 21 Udp::~Udp() 22 { 23 if(sock != -1){ 24 close(sock); 25 } 26 } 27 28 int Udp::Recv( 29 char* buff, 30 int len, 31 unsigned int &nip, 32 unsigned short &nport, 33 char *errbuff 34 ) 35 { 36 int result = 0; 37 socklen_t socklen = sizeof(sockaddr); 38 39 sockaddr_in addr; 40 memset(&addr, 0, sizeof(sockaddr_in)); 41 42 /*设置超时时间*/ 43 fd_set fds; 44 FD_ZERO(&fds); 45 FD_SET(sock, &fds); 46 47 timeval tv; 48 tv.tv_sec = 3; 49 tv.tv_usec = 0; 50 51 result = select(sock + 1, &fds, NULL, NULL, &tv); 52 CURRENTERROR(errbuff); 53 if(-1 == result){ 54 return -1; 55 } 56 else if(0 == result){ 57 return 0; 58 } 59 60 result = recvfrom(sock, buff, len, 0, (sockaddr*)&addr, &socklen); 61 CURRENTERROR(errbuff); 62 63 /*记录对方网络格式的地址和端口*/ 64 nip = addr.sin_addr.s_addr; 65 nport = addr.sin_port; 66 67 return result; 68 } 69 70 int Udp::Send( 71 char* buff, 72 int len, 73 unsigned int nip, 74 unsigned short nport, 75 char *errbuff 76 ) 77 { 78 int result = 0; 79 socklen_t socklen = sizeof(sockaddr); 80 81 sockaddr_in addr; 82 memset(&addr, 0, sizeof(sockaddr_in)); 83 addr.sin_family = AF_INET; 84 addr.sin_addr.s_addr = nip; 85 addr.sin_port = nport; 86 87 result = sendto(sock, buff, len, 0, (sockaddr*)&addr, socklen); 88 CURRENTERROR(errbuff); 89 90 return result; 91 } 92 93 int Udp::Open(char *errbuff) 94 { 95 if(sock != -1){ 96 close(sock); 97 sock = -1; 98 } 99 100 sock = socket(AF_INET, SOCK_DGRAM, 0);101 CURRENTERROR(errbuff);102 if(sock == -1){103 return -1;104 }105 106 return 0;107 }108 109 void Udp::Close()110 {111 if(sock != -1){112 close(sock);113 sock = -1;114 }115 }116 117 int Udp::Bind(char *ip, unsigned short port, char* errbuff)118 {119 sockaddr_in saddr;120 memset(&saddr, 0, sizeof(sockaddr_in));121 saddr.sin_family = AF_INET;122 saddr.sin_addr.s_addr = inet_addr(ip);123 saddr.sin_port = htons(port);124 125 if(saddr.sin_addr.s_addr == INADDR_NONE){ 126 strcpy(errbuff, "Invalid IP format");127 return -1;128 }129 130 int result;131 result = bind(sock, (sockaddr*)&saddr, sizeof(sockaddr_in));132 CURRENTERROR(errbuff); 133 134 return result;135 }
Server类:利用Udp类,提供UDP服务
server.h
1 // server.h 2 #ifndef __SERVER_H__ 3 #define __SERVER_H__ 4 5 #include "udp.h" 6 7 class Server 8 { 9 private:10 Udp udp;11 unsigned int reqs; // 已经接收到的请求数量12 13 static Server *pser; // 本对象指针14 15 Server(); // 在一个程序中,只允许一个对象16 public:17 static Server* GetInstance(); // 获取该对象18 ~Server();19 20 int Start(unsigned short port); // 启动UDP服务21 int Listen(); // 监听网络请求22 int Stat(); // 统计请求速率23 };24 25 #endif
server.cpp
1 #include "server.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include6 #include 7 #include 8 9 Server *Server::pser = NULL; 10 11 static void* ServiceThread(void *arg) // UDP服务线程处理函数 12 { 13 if(!arg) return NULL; 14 15 Server *pser = (Server *)arg; 16 pser->Listen(); 17 } 18 19 static void* ServiceStat(void *arg) // 请求速率统计线程处理函数 20 { 21 if(!arg) return NULL; 22 23 Server *pser = (Server *)arg; 24 pser->Stat(); 25 } 26 27 int Server::Stat() 28 { 29 float req0, req1; 30 int slen = 3000000; 31 32 // 每隔3秒统计一次 33 while(true){ 34 req0 = reqs; 35 usleep(slen); 36 req1 = reqs; 37 38 printf("Req: %.2f r/s\n", (req1 - req0)/(slen/1000000)); 39 } 40 } 41 42 Server::Server() 43 { 44 reqs = 0; 45 } 46 47 Server::~Server() 48 { 49 if(pser){ 50 delete pser; 51 } 52 } 53 54 Server* Server::GetInstance() 55 { 56 if(!pser){ //第一次运行,创建新对象 57 pser = new Server; 58 } 59 60 return pser; 61 } 62 63 int Server::Listen() 64 { 65 char buff[1514]; 66 unsigned int nip; 67 unsigned short nport; 68 int len; 69 70 SlotAck sa; // 这里还没有赋值为加密后的时间戳 71 while(true){ 72 /*等待请求,并作出应答*/ 73 len = udp.Recv(buff, 1514, nip, nport, NULL); 74 if(len > 0) 75 { 76 udp.Send((char *)&sa, sizeof(sa), nip, nport, NULL); 77 reqs++; 78 } 79 } 80 81 return 0; 82 } 83 84 int Server::Start(unsigned short port) 85 { 86 printf("Server: Open...\n"); 87 char errbuff[ERRBUFFLENGTH]; 88 if(-1 == udp.Open(errbuff)){ 89 printf("%s\n", errbuff); 90 return -1; 91 } 92 93 printf("Server: Bind (%d)...\n", port); 94 char ip[] = "0.0.0.0"; 95 if(-1 == udp.Bind(ip, port, errbuff)){ 96 printf("%s\n", errbuff); 97 return -1; 98 } 99 100 // 启动两个线程101 pthread_t pth;102 pthread_create(&pth, NULL, ServiceThread, this);103 pthread_create(&pth, NULL, ServiceStat, this);104 105 return 0;106 }
Client类:利用Udp类,完成时间戳请求服务
client.h
1 // client.h 2 #ifndef __CLIENT_H__ 3 #define __CLIENT_H__ 4 5 #include "udp.h" 6 7 class Client 8 { 9 private:10 Udp udp;11 unsigned int nserip; // UDP服务器的地址12 unsigned short nserport; // UDP服务器的端口13 14 static Client *pclt; // 本对象指针15 16 Client();17 public:18 static Client* GetInstance();19 ~Client();20 21 int Start(char* addr, unsigned short port);22 int Request();23 };24 25 #endif
client.cpp
1 #include "client.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include6 #include 7 #include 8 9 Client *Client::pclt = NULL;10 11 static void* ServiceThread(void *arg) /*请求线程处理函数*/12 {13 if(!arg) return NULL;14 15 Client *pser = (Client *)arg;16 pser->Request();17 }18 19 Client::Client()20 {21 }22 23 Client::~Client()24 {25 if(pclt){26 delete pclt;27 }28 }29 30 Client* Client::GetInstance()31 {32 if(!pclt){33 pclt = new Client;34 }35 36 return pclt;37 }38 39 int Client::Request()40 {41 char buff[1514];42 int len;43 SlotReq sr;44 45 unsigned int nip;46 unsigned short nport;47 while(true){48 //每隔1秒请求一次,并等待相应49 len = udp.Send((char*)&sr, sizeof(sr), nserip, nserport, NULL);50 len = udp.Recv(buff, 1514, nip, nport, NULL);51 if(len>0){52 printf("Ack!\n");53 }54 else{55 printf("NoAck!\n");56 }57 usleep(1000000);58 }59 60 return 0;61 }62 63 int Client::Start(char* addr, unsigned short port)64 {65 printf("Client: Open...\n");66 char errbuff[ERRBUFFLENGTH];67 if(-1 == udp.Open(errbuff)){68 printf("%s\n", errbuff);69 return -1;70 }71 72 nserport = htons(port);73 nserip = inet_addr(addr);74 75 pthread_t pth;76 pthread_create(&pth, NULL, ServiceThread, this);77 78 return 0;79 }
Attack类:利用Udp类,完成flood攻击
attack.h
#ifndef __ATTACK_H__#define __ATTACK_H__#include "udp.h"class Attack{private: Udp udp; unsigned int nserip; unsigned short nserport; static Attack *pclt; Attack();public: static Attack* GetInstance(); ~Attack(); int Start(char* addr, unsigned short port); int Request();};#endif
attack.cpp
1 #include "attack.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include6 #include 7 #include 8 9 Attack *Attack::pclt = NULL;10 11 static void* ServiceThread(void *arg)12 {13 if(!arg) return NULL;14 15 Attack *pser = (Attack *)arg;16 pser->Request();17 }18 19 Attack::Attack()20 {21 }22 23 Attack::~Attack()24 {25 if(pclt){26 delete pclt;27 }28 }29 30 Attack* Attack::GetInstance()31 {32 if(!pclt){33 pclt = new Attack;34 }35 36 return pclt;37 }38 39 int Attack::Request()40 {41 char buff[1514];42 int len;43 SlotReq sr;44 45 unsigned int nip;46 unsigned short nport;47 while(true){48 len = udp.Send((char*)&sr, sizeof(sr), nserip, nserport, NULL);49 //usleep(1000000);50 }51 52 return 0;53 }54 55 int Attack::Start(char* addr, unsigned short port)56 {57 printf("Attack: Open...\n");58 char errbuff[ERRBUFFLENGTH];59 if(-1 == udp.Open(errbuff)){60 printf("%s\n", errbuff);61 return -1;62 }63 /*64 printf("Attack: Bind (%d)...\n", port-1);65 char ip[] = "0.0.0.0";66 if(-1 == udp.Bind(ip, port-1, errbuff)){67 printf("%s\n", errbuff);68 return -1;69 }70 */ 71 nserport = htons(port);72 nserip = inet_addr(addr);73 74 pthread_t pth;75 pthread_create(&pth, NULL, ServiceThread, this);76 77 return 0;78 }
Bash类:提供界面交互功能
bash.h
#ifndef __BASH_H__#define __BASH_H__#includeclass Bash{private: pthread_t pth;public: Bash(); ~Bash(); int CmdHdl(char *cmd); int Start(char* errbuff); int Stop(); int IOE(); void HelloMsg(); void ByeMsg(); int AddrCheck(char* ip);};#endif
bash.cpp
1 #include "bash.h" 2 #include "defs.h" 3 #include "server.h" 4 #include "client.h" 5 #include "attack.h" 6 #include7 using namespace std; 8 #include 9 #include 10 #include 11 12 #define inhead() printf("root@hs # ") 13 14 void* BashThread(void *arg) 15 { 16 Bash *pbash = (Bash*)arg; 17 pbash->IOE(); 18 19 return NULL; 20 } 21 22 void Bash::HelloMsg() 23 { 24 system("clear"); 25 printf("------------------------------------------------------------\n"); 26 printf("-------------------------Bash Start-------------------------\n"); 27 printf("------------------------------------------------------------\n"); 28 } 29 30 void Bash::ByeMsg() 31 { 32 printf("------------------------------------------------------------\n"); 33 printf("--------------------------Bash end--------------------------\n"); 34 printf("------------------------------------------------------------\n"); 35 } 36 37 Bash::Bash() 38 { 39 40 } 41 42 Bash::~Bash() 43 { 44 45 } 46 47 int Bash::AddrCheck(char* ip) 48 { 49 int result = 0; 50 int a[4]; 51 52 result = sscanf(ip, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 53 if(result < 4){ 54 return -1; 55 } 56 57 for(int i = 0; i<4; i++){ 58 if(a[i] >= 255 || a[i] < 0) 59 return -1; 60 } 61 62 return 0; 63 } 64 65 int Bash::Start(char* errbuff) 66 { 67 int result; 68 result = pthread_create(&pth, NULL, BashThread, this); 69 if(result){ 70 CURRENTERROR(errbuff); 71 return -1; 72 } 73 74 pthread_join(pth, NULL); 75 76 return 0; 77 } 78 79 int Bash::CmdHdl(char *cmd) 80 { 81 char cmdh[32], cmdl[BASH_MAXCMDLENGTH - 32]; 82 83 if(!cmd){ 84 return 0; 85 } 86 87 while(*cmd != '\0' && (*cmd == ' ' || *cmd == '\t' || *cmd == '\n')){ 88 cmd++; 89 } 90 91 int i = 0; 92 while(*cmd != '\0' && *cmd != ' ' && *cmd != '\t'){ 93 cmdh[i++] = *cmd++; 94 } 95 cmdh[i] = 0; 96 97 while(*cmd != '\0' && (*cmd == ' ' || *cmd == '\t' || *cmd == '\n')){ 98 cmd++; 99 }100 101 i = 0;102 while(*cmd != '\0'){103 cmdl[i++] = *cmd++;104 }105 cmdl[i] = 0;106 107 if(!strcmp(cmdh, "quit") || !strcmp(cmdh, "q")){108 ByeMsg();109 pthread_exit(NULL);110 }111 else if(!strcmp(cmdh, "ser") || !strcmp(cmdh, "s")){112 Server::GetInstance()->Start(2223);113 }114 else if(!strcmp(cmdh, "clt") || !strcmp(cmdh, "c")){115 if(-1 == AddrCheck(cmdl)){116 printf("IP address [%s] is invalid.\n", cmdl);117 return -1;118 }printf("IP address [%s] is invalid.\n", cmdl);119 Client::GetInstance()->Start(cmdl, 2223);120 }121 else if(!strcmp(cmdh, "att") || !strcmp(cmdh, "a")){122 if(-1 == AddrCheck(cmdl)){123 printf("IP address [%s] is invalid.\n", cmdl);124 return -1;125 }126 Attack::GetInstance()->Start(cmdl, 2223);127 }128 else{129 printf("\"%s\" is invalid!\n", cmdh);130 }131 132 return 0;133 }134 135 int Bash::IOE()136 {137 HelloMsg();138 139 char ibuff[BASH_MAXCMDLENGTH];140 while(true){141 inhead();142 gets(ibuff);143 CmdHdl(ibuff);144 }145 146 return 0;147 }148 149 int Bash::Stop()150 {151 152 }