UDP畅聊系统简单版本

发布时间:2020-07-16 23:40:42 作者:yayaru9240
来源:网络 阅读:372

带有数据存储的模型图

UDP畅聊系统简单版本

总体的框架

UDP畅聊系统简单版本

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)



推荐阅读:
  1. 简单聊一聊Ansible自动化运维
  2. unix 网络编程udp简单例程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

server include public

上一篇:ImportError: No module named pkg_resources解决方法

下一篇:ICP年报又要开始了,不知道在哪申报的看过来了

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》