带有数据存储的模型图
总体的框架
server中
udp_server.h
其中add_user函数为添加新上线用户信息
1 #pragma once 2 #include <iostream> 3 #include <map> 4 using namespace std; 5 #include "data_pool.h" 6 #include <pthread.h> 7 #include <stdlib.h> 8 class udp_server 9 { 10 public: 11 udp_server(const std::string &ip="192.168.137.129",const short &port=808 0); 12 ~udp_server(); 13 void init(); 14 int recv_data(); 15 int send_data(struct sockaddr_in& client,socklen_t len,string& msg); 16 int broadcast(); 17 protected: 18 void add_user(string& key_ip,struct sockaddr_in& client); 19 protected: 20 string _ip; 21 short _port; 22 int _sock; 23 std::map<string,struct sockaddr_in> _online_user; 24 pool_data _pool_data; 25 };
udp_server.cpp
1 #include "udp_server.h" 2 #include "comm.h" 3 #include "data_pool.h" 4 5 udp_server::udp_server(const std::string &default_ip,const short &default_po rt) 6 :_ip(default_ip) 7 ,_port(default_port) 8 ,_sock(-1) 9 {} 10 11 udp_server::~udp_server() 12 { 13 if(_sock > 0) 14 close(_sock); 15 } 16 17 void udp_server::init() 18 { 19 _sock=socket(AF_INET,SOCK_DGRAM,0); 20 if(_sock <0) 21 { 22 print_log(strerror(errno),__FUNCTION__,__LINE__); 23 exit(1); 24 } 25 struct sockaddr_in local; 26 socklen_t len=sizeof(local); 27 local.sin_family=AF_INET; 28 local.sin_port=htons(_port); 29 if(_ip.c_str()=="any") 30 { 31 local.sin_addr.s_addr=htonl(INADDR_ANY); 32 } 33 else 34 local.sin_addr.s_addr=inet_addr(_ip.c_str()); 35 if(bind(_sock,(struct sockaddr*)&local,len)<0) 36 { 37 print_log(strerror(errno),__FUNCTION__,__LINE__); 38 exit(2); 39 } 40 } 41 42 int udp_server::recv_data() 43 { 44 std::string _out; 45 struct sockaddr_in client; 46 socklen_t len=sizeof(client); 47 char buf[_SIZE_]; 48 buf[0]='/0'; 49 ssize_t _size=recvfrom(_sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&clie nt,&len); 50 if(_size < 0) 51 { 52 print_log(strerror(errno),__FUNCTION__,__LINE__); 53 } 54 else if(_size == 0) 55 { 56 const char *msg="client closed..."; 57 print_log(msg,__FUNCTION__,__LINE__); 58 } 59 else 60 { 61 buf[_size]='/0'; 62 _out=buf; 63 string key_ip=inet_ntoa(client.sin_addr); 64 print_log(key_ip.c_str(),__FUNCTION__,__LINE__); 65 add_user(key_ip,client); 66 _pool_data.put_data(_out); 67 } 68 return _size; 69 } 70 71 void udp_server::add_user(string &key_ip,struct sockaddr_in &client) 72 { 73 std::map<std::string,struct sockaddr_in>::iterator _iter=_online_user.f ind(key_ip); 74 if(_iter==_online_user.end()) 75 { 76 _online_user.insert(std::pair<std::string,struct sockaddr_in>(key_i p,client)); 77 } 78 else 79 return; 80 } 81 82 int udp_server::send_data(struct sockaddr_in &client,socklen_t len,std::str ing& msg) 83 { 84 ssize_t _size=sendto(_sock,msg.c_str(),msg.size(),0,(struct sockaddr*)& client,len); 85 if( _size <0) 86 { 87 print_log(strerror(errno),__FUNCTION__,__LINE__); 88 exit(1); 89 } 90 91 return _size; 92 } 93 int udp_server::broadcast() 94 { 95 std::string _in; 96 std::map<std::string,struct sockaddr_in>::iterator _iter=_online_user.b egin(); 97 while(_iter!=_online_user.end()) 98 { 99 //send_data(_iter->second,sizeof(_iter->second),_in); 100 _pool_data.get_data(_in); 101 _iter++; 102 } 103 return 0; 104 }
server_main.cpp中,两个线程处理函数分别处理接收与广播数据
1 #include "udp_server.h" 2 3 void Usage(const char* proc) 4 { 5 cout<<"Usage:"<<proc<<" [ip] [port]"<<endl; 6 } 7 8 void* recv(void* arg) 9 { 10 udp_server* _ser=(udp_server*)arg; 11 while(1) 12 { 13 _ser->recv_data(); 14 } 15 } 16 17 void* broad_cast(void* arg) 18 { 19 udp_server* _ser=(udp_server*)arg; 20 while(1) 21 { 22 _ser->broadcast(); 23 } 24 } 25 26 int main(int argc,const char* argv[]) 27 { 28 if(argc!=3) 29 { 30 Usage(argv[0]); 31 exit(1); 32 } 33 string ip=argv[1]; 34 int port=atoi(argv[2]); 35 udp_server _ser(ip,port); 36 _ser.init(); 37 pthread_t tid1; 38 pthread_t tid2; 39 pthread_create(&tid1,NULL,recv,(void*)&_ser); 40 pthread_create(&tid2,NULL,broad_cast,(void*)&_ser); 41 42 pthread_join(tid1,NULL); 43 pthread_join(tid2,NULL); 44 // while(1) 45 // { 46 // std::string msg; 47 // if(_ser.recv_data(msg)>0) 48 // { 49 // cout<<"client say:"<<msg; 50 // _ser.broadcast(msg); 51 // } 52 // } 53 return 0; 54 }
client中进行发送消息和接收消息
udp_client.h
1 #pragma once 2 3 #include <iostream> 4 using namespace std; 5 #include <stdio.h> 6 #include <assert.h> 7 8 class udp_client 9 { 10 public: 11 udp_client(const string &default_ip="192.168.137.129",const short &defa ult_port=8080); 12 ~udp_client(); 13 void init(); 14 int recv_data(string& _out); 15 int send_data(string& _in); 16 protected: 17 string _ip; 18 short _port; 19 int _sock; 20 };
udp_client.cpp
1 #include "udp_client.h" 2 #include "comm.h" 3 4 udp_client::udp_client(const string &default_ip,const short &default_port) 5 :_ip(default_ip) 6 ,_port(default_port) 7 ,_sock(-1) 8 {} 9 10 udp_client::~udp_client() 11 { 12 if(_sock > 0) 13 close(_sock); 14 } 15 16 17 void udp_client::init() 18 { 19 _sock=socket(AF_INET,SOCK_DGRAM,0); 20 if(_sock <0) 21 { 22 print_log(strerror(errno),__FUNCTION__,__LINE__); 23 exit(1); 24 } 25 } 26 27 int udp_client::recv_data(string &_out) 28 { 29 struct sockaddr_in server; 30 socklen_t len=sizeof(server); 31 char buf[_SIZE_]; 32 buf[0]='/0'; 33 ssize_t _size=recvfrom(_sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&ser ver,&len); 34 if(_size < 0) 35 { 36 print_log(strerror(errno),__FUNCTION__,__LINE__); 37 } 38 else if(_size == 0) 39 { 40 const char *msg="server closed..."; 41 print_log(msg,__FUNCTION__,__LINE__); 42 } 43 else 44 { 45 buf[_size]='/0'; 46 _out=buf; 47 } 48 return _size; 49 } 50 51 int udp_client::send_data(string& _in) 52 { 53 struct sockaddr_in server; 54 server.sin_family=AF_INET; 55 server.sin_port=htons(_port); 56 server.sin_addr.s_addr=inet_addr(_ip.c_str()); 57 socklen_t len=sizeof(server); 58 ssize_t _size=sendto(_sock,_in.c_str(),_in.size(),0,(struct sockaddr*)& server,len); 59 if(_size < 0) 60 { 61 print_log(strerror(errno),__FUNCTION__,__LINE__); 62 } 63 return _size; 64 }
client_main.cpp
1 #include "udp_client.h" 2 #include "comm.h" 3 4 void Usage(const char* proc) 5 { 6 assert(proc); 7 cout<<"Usage:"<<proc<<"[ip] [port]"<<endl; 8 } 9 int main(int argc,char* argv[]) 10 { 11 if(argc!=3) 12 { 13 Usage(argv[0]); 14 exit(1); 15 } 16 string ip=argv[1]; 17 int port=atoi(argv[2]); 18 19 std::string msg; 20 std::string rec; 21 std::string _in; 22 char buf[_SIZE_]; 23 udp_client _cli(ip,port); 24 _cli.init(); 25 _cli.send_data(msg); 26 while(1) 27 { 28 cout<<"please input:"; 29 fflush(stdout); 30 memset(buf,'/0',sizeof(buf)); 31 ssize_t _s=read(0,buf,sizeof(buf)-1); 32 if(_s >0) 33 { 34 rec=buf; 35 _cli.send_data(rec); 36 } 37 if(buf=="quit") 38 { 39 cout<<"no data send"<<endl; 40 return -1; 41 } 42 sleep(2); 43 if(_cli.recv_data(_in)>0) 44 { 45 cout<<"server echo:"<<_in; 46 } 47 } 48 return 0; 49 }
Makefile
1 ROOT_PATH=$(shell pwd) 2 SERVER=$(ROOT_PATH)/server 3 CLIENT=$(ROOT_PATH)/client 4 COMM=$(ROOT_PATH)/comm 5 DATA_POOL=$(ROOT_PATH)/data_pool 8 SERVER_BIN=udp_server 9 CLIENT_BIN=udp_client 10 11 12 INCLUDE=-I$(COMM) -I$(DATA_POOL) 13 INCLUDE+=-I$(DATA_POOL) 14 INCLUDE+=-I$(ROOT_PATH)/lib/include 15 16 CC=g++ 17 FLAGS= 18 LDFLAGS=-lpthread #-static 19 20 SER_SRC=$(shell ls -R $(SERVER) |grep -E '*.cpp') 21 SER_SRC+=$(shell ls -R $(COMM) |grep -E '*.cpp') 22 SER_SRC+=$(shell ls -R $(DATA_POOL) |grep -E '*.cpp') 23 SER_OBJ=$(SER_SRC:.cpp=.o) 25 CLI_SRC=$(shell ls -R $(CLIENT) |grep -E '*.cpp') 26 CLI_SRC+=$(shell ls -R $(COMM) |grep -E '*.cpp') 27 CLI_OBJ=$(CLI_SRC:.cpp=.o) 28 29 .PHONY:all 30 all:$(SERVER_BIN) $(CLIENT_BIN) 31 $(SERVER_BIN):$(SER_OBJ) 32 @$(CC) -o $@ $^ $(LDFLAGS) 33 @echo "Linking [ $^ ] to [ $@ ] ...done" 34 $(CLIENT_BIN):$(CLI_OBJ) 35 @$(CC) -o $@ $^ $(LDFLAGS) 36 @echo "Linking [ $^ ] to [ $@ ] ...done" 37 %.o:$(COMM)/%.cpp 38 @$(CC) -c $< $(INCLUDE) 39 @echo "Compling [ $(shell basename $<) ] to [ $@ ] ...done" 40 %.o:$(DATA_POOL)/%.cpp 41 @$(CC) -c $< $(INCLUDE) 42 @echo "Compling [ $(shell basename $<) ] to [ $@ ] ...done" 43 %.o:$(SERVER)/%.cpp 44 @$(CC) -c $< $(INCLUDE) 45 @echo "Compling [ $(shell basename $<) ] to [ $@ ] ...done" 46 %.o:$(CLIENT)/%.cpp 47 @$(CC) -c $< $(INCLUDE) 48 @echo "Compling [ $(shell basename $<) ] to [ $@ ] ...done" 49 62 .PHONY:clean 63 clean: 64 @rm -f *.o $(SERVER_BIN) $(CLIENT_BIN) 65 @echo "cleaning done..." 66 67 .PHONY:debug 68 debug: 69 @echo $(SER_SRC) 70 @echo $(CLI_SRC)
原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/219632.html