当前位置: 首页 > news >正文

台州网站策划台州网站策划pinterest官网入口

台州网站策划台州网站策划,pinterest官网入口,怎么通过贷款网站找做贷款客户,开一家网店前言#xff1a;本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以#xff0c; 我们主要就是要实现客户端以及服务端的逻辑代码。 那么#xff0c; 接下来开始我们的学习吧。 ps:本节内容…         前言本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以 我们主要就是要实现客户端以及服务端的逻辑代码。 那么 接下来开始我们的学习吧。         ps:本节内容建议了解socket套接字的接口的友友们进行观看哦本节内容中涉及到的接口都不会讲解 直接就用了。 目录 整体代码 Udpclient UdpServer main配合UdpServer UdpServer的入口  准备文件 实现步骤 实现服务端客户端的收发消息 Udpserver Init函数 run函数  UdpServer析构 Udpclient 实现客户端之间的聊天功能 Udpserver Udpclient 运行结果 整体代码 先上整体代码 Udpclient #includeiostream using namespace std; #includestring #includesys/types.h #includeLog.hpp #includesys/socket.h #includepthread.h #includearpa/inet.h #includestring.h #includenetinet/in.h Log lg;class ThreadData { public:sockaddr_in server;int sockfd; };void* recv_message(void* args) {char buffer[1024];ThreadData* td static_castThreadData*(args); while (true){//接收数据sockaddr_in temp;socklen_t len;string info;ssize_t s recvfrom(td-sockfd, buffer, sizeof(buffer) - 1, 0, (sockaddr*)temp, len);if (s 0){lg(Error, recv error, error: %d, strerror: %s, errno, strerror(errno));continue;}buffer[s] 0;info buffer;cout info endl;}}void* send_message(void* args) {ThreadData* td static_castThreadData*(args);string message;while (true){ getline(cin, message); //获取数据//发送数据sendto(td-sockfd, message.c_str(), message.size(), 0, (sockaddr*)td-server, sizeof(td-server));} }int main(int argc, char* argv[]) {if (argc ! 3){cout Client server endl;}//先拿到套接字的参数string serverip argv[1];uint16_t serverport stoi(argv[2]);ThreadData td;//创建套接字与打开网卡memset(td.server, 0, sizeof(td.server));td.server.sin_family AF_INET;td.server.sin_port htons(serverport);td.server.sin_addr.s_addr inet_addr(serverip.c_str());td.sockfd socket(AF_INET, SOCK_DGRAM, 0); //创建文件描述符, 网卡的文件描述符 网络传输就是使用网络文件描述符找到对应的文件内的数据if (td.sockfd 0){lg(Error, client create sockfd error, errno: %d, strerror: %s, errno, strerror(errno));exit(1);}//创建线程 然后运行线程 等待线程pthread_t recv, send;pthread_create(recv, nullptr, recv_message, td);pthread_create(send, nullptr, send_message, td);pthread_join(recv, nullptr);pthread_join(send, nullptr);close(td.sockfd);return 0; } UdpServer #includeiostream using namespace std; #includesys/types.h #includestring #includesys/socket.h #includearpa/inet.h #includestring.h #includestrings.h #includeLog.hpp #includefunctional #includenetinet/in.h #includeunordered_mapint defaultport 8080; string defaultip 0.0.0.0;using func_t functionstring(string, sockaddr_in, unordered_mapstring, sockaddr_in); Log lg;enum {SockError 2,BindError 3,RecvError 4, };class UdpServer { public:UdpServer(uint16_t port defaultport) : port_(port), ip_(defaultip), isrunning_(false){}void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(port_);local.sin_addr.s_addr inet_addr(ip_.c_str());sockfd_ socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ 0){lg(Fatal, create sock error, errno: %d, strerror: %s, errno, strerror(errno));exit(SockError);}lg(Info, create sock success);//绑定if (bind(sockfd_, (sockaddr*)local, sizeof(local)) 0) {lg(Fatal, bind error, errno: %d, strerror: %s, errno, strerror(errno));exit(BindError);}lg(Info, bind success);}void BroadCast(string message, unordered_mapstring, sockaddr_in clients){cout 1 endl;for (auto e : clients){sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)e.second, sizeof(e.second));}cout 2 endl;}void run(func_t func){isrunning_ true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)client, client_len);if (s 0) {lg(Waring, recvfrom error, errno: %d, strerror: %s, errno, strerror(errno));continue;}inbuffer[s] 0;//处理数据//创建套接字 用来监听是哪一个客户端string message inbuffer;message func(message, client, clients);//处理完成后 返回发送给客户端BroadCast(message, clients);// sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)client, sizeof(client));}}~UdpServer(){if (sockfd_ 0) close(sockfd_); } private:int sockfd_;uint16_t port_;string ip_;bool isrunning_;unordered_mapstring, sockaddr_in clients;}; main配合UdpServer UdpServer的入口  #includeUdpServer.hpp #includememorystring Handler(string message, sockaddr_in client, unordered_mapstring, sockaddr_in clients) {string tmp inet_ntoa(client.sin_addr) to_string(client.sin_port);if (!clients.count(tmp)){clients[tmp] client; cout ip inet_ntoa(client.sin_addr) : port client.sin_port has add in talk room endl;}message [ string(inet_ntoa(client.sin_addr)) : to_string(client.sin_port) ]#: message; return message; }int main(int argc, char* argv[]) {if (argc ! 2){cout has return endl;return 1;}//uint16_t serverport stoi(argv[1]); unique_ptrUdpServer svr(new UdpServer(serverport));//svr-Init();svr-run(Handler);return 0; } 准备文件 我们要准备三个文件 Udpclient.cc——用来运行起来客户端        UdpServer.hpp——用来实现服务端的各种接口        main.cc——用来运行起来服务端 除了这三个主要的文件。 其实博主还准备了两个可以忽略的文件为了方便。 一个是博主自己写的日志程序 用来打印日志。 一个是makefile 方便编译。  如果没有日志程序的话打印错误信息时直接cout printf打印即可。 makefile建议带上 方便编译养成好习惯。 实现步骤 注意 一步到位是很难的。 所以我们先实现简单的功能 再实现困难的功能。 这里简单的功能就是先让客户端能够将数据发给服务端了 然后服务端接收到消息后再将数据返回给客户端。 这里困难的功能就是当多个客户端如何看到互相的信息。然后如何能够一遍发信息一边收信息。  实现服务端客户端的收发消息 Udpserver 实现逻辑Udpserver.hpp中封装一个类。这个类里面封装一些接口 然后我们在main函数中创建类对象 在执行接口操作。 所以 先封装一个类 将要实现的接口以及要用到的变量写上 实现一个框架 #includeiostream using namespace std; #includestringint defaultport 8080; //默认的端口号我们要创建一个默认的端口号 string defaultip 0.0.0.0; //在服务器中使用套接字的时候 bind函数不能绑定公网IP 因为 //服务器的公网IP可能是虚拟的 注意IP地址是和网卡挂钩的 一个网卡只能有一个IP地址。 //绑定ip地址就是说在绑定网卡也就是说绑定某个IP地址后就只能监听这一个网卡的消息了。 但是 //有些机器是有很多张网卡的 所以就有一个默认IP:0.0.0.0 绑定这个IP就能监听在本机器下面 //所有的网卡的信息。 Log lg;class UdpServer { public:UdpServer(uint16_t port defaultport) : port_(port), ip_(defaultip), isrunning_(false){}void Init(){}void run(func_t func){}~UdpServer(){} private:int sockfd_; //服务端的网卡文件的编号uint16_t port_; //服务器起来后的端口号string ip_; //服务器起来的时候所在的ip地址bool isrunning_; //服务器是否正在运行}; 下面是main.cpp里面的内容 直接启动服务端。  #includeUdpServer.hpp #includememoryint main(int argc, char* argv[]) {if (argc ! 2){cout has return endl;return 1;}//uint16_t serverport stoi(argv[1]); unique_ptrUdpServer svr(new UdpServer(serverport));//svr-Init();svr-run();return 0; } Init函数 Udpserver里面的Init函数 这个函数用来绑定服务端的套接字的。 什么是绑定 博主目前的理解就是将我们运行的服务端这个程序能够和网卡建立起关系。          这个关系中 关系的两端是我们运行的服务端程序和socket网卡文件网卡文件就代表了网卡。关系的纽带是ip地址和端口号。 利用ip地址和端口号来将我们的服务端程序绑定给网卡 这个时候因为网卡的工作性质 其他的进程都不能再绑定网卡了 直到我们的服务端退出。  void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(port_);local.sin_addr.s_addr inet_addr(ip_.c_str());sockfd_ socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ 0){lg(Fatal, create sock error, errno: %d, strerror: %s, errno, strerror(errno));exit(SockError);}lg(Info, create sock success);//绑定if (bind(sockfd_, (sockaddr*)local, sizeof(local)) 0) {lg(Fatal, bind error, errno: %d, strerror: %s, errno, strerror(errno));exit(BindError);}lg(Info, bind success);}run函数  我们这里思考一个问题 我们要实现的其实是服务端与客户端之间收发消息。 所以 我们就要客户端先发 然后服务端收消息。  然后 服务端收到消息将消息 处理一下 再将消息发回客户端。 所以这个过程中服务端有三个主要的动作 一个是收一个是处理 一个是发。          然后我们的处理怎么处理 我们可以将处理动作暴露出去  交给main.cpp来决定。 ——利用回调函数 main.cpp中将要执行的动作作为函数传给run函数。  如下为接口 //这里的func_t是一个回调函数的类型。 什么类型 使用包装器包装的注意//包含头文件functionalusing func_t functionstring(string); void run(func_t func){isrunning_ true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)client, client_len);if (s 0) {lg(Waring, recvfrom error, errno: %d, strerror: %s, errno, strerror(errno));continue;}inbuffer[s] 0;//处理数据//创建套接字 用来监听是哪一个客户端string message inbuffer;message func(message);//这里的处理使用一个外部的接口//处理完成后 返回发送给客户端sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)client, sizeof(client));}} UdpServer析构 析构函数不解释 ~UdpServer(){if (sockfd_ 0) close(sockfd_); } Udpclient 客户端就是给对应的服务端发送数据。 数据被服务端处理后接收即可: #includeiostream #includecstdlib #includeunistd.h using namespace std; #includesys/types.h #includestrings.h #includesys/socket.h #includenetinet/in.h #includearpa/inet.h #includecstring #includestring//./udpclient serverip serverport int main(int argc, char* argv[]) {if (argc ! 3){cout has return endl;return 1;}//string serverip argv[1];uint16_t serverprot stoi(argv[2]);//创建套接字struct sockaddr_in server;bzero(server, sizeof(server));server.sin_family AF_INET;server.sin_port htons(serverprot);server.sin_addr.s_addr inet_addr(serverip.c_str());socklen_t serlen sizeof(server);int sockfd socket(AF_INET, SOCK_DGRAM, 0);if (sockfd 0){cout socker error endl; return 1;}string message;char buffer[1024];while(true){ cout please Enter: endl;getline(cin, message); //发送数据sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)server, serlen);cout yes endl;//接收数据sockaddr_in temp;socklen_t socklen;ssize_t sz recvfrom(sockfd, (void*)buffer, sizeof(buffer) - 1, 0, (sockaddr*)temp, socklen); //sockfd其实就是网卡的pidif(sz 0){buffer[sz] 0;cout buffer endl;}}close(sockfd);return 0; } 实现客户端之间的聊天功能 Udpserver 实现客户端之间的聊天可是说是在上面的代码中改两个地方。 一个是创建一个哈希表存储有多少客户端连接了服务端。 然后以后发消息就直接便利整个哈希表 然后将数据发给每一个客户端。 如下 #includeiostream using namespace std; #includesys/types.h #includestring #includesys/socket.h #includearpa/inet.h #includestring.h #includestrings.h #includeLog.hpp #includefunctional #includenetinet/in.h #includeunordered_mapint defaultport 8080; string defaultip 0.0.0.0;//包装类要进行修改一下 using func_t functionstring(string, sockaddr_in, unordered_mapstring, sockaddr_in); Log lg;enum {SockError 2,BindError 3,RecvError 4, };class UdpServer { public:UdpServer(uint16_t port defaultport) : port_(port), ip_(defaultip), isrunning_(false){}//Init不变void Init(){//先创建套接字变量并且完成初始化。 然后就创建网卡文件sockaddr_in local;memset(local, 0, sizeof(local));local.sin_family AF_INET;local.sin_port htons(port_);local.sin_addr.s_addr inet_addr(ip_.c_str());sockfd_ socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ 0){lg(Fatal, create sock error, errno: %d, strerror: %s, errno, strerror(errno));exit(SockError);}lg(Info, create sock success);//绑定if (bind(sockfd_, (sockaddr*)local, sizeof(local)) 0) {lg(Fatal, bind error, errno: %d, strerror: %s, errno, strerror(errno));exit(BindError);}lg(Info, bind success);}//遍历哈希表将数据分发给所有的客户端void BroadCast(string message, unordered_mapstring, sockaddr_in clients){cout 1 endl;for (auto e : clients){sendto(sockfd_, message.c_str(), message.size(), 0, (sockaddr*)e.second, sizeof(e.second));}cout 2 endl;}void run(func_t func){isrunning_ true;char inbuffer[1024];while (isrunning_){memset(inbuffer, 0, sizeof(inbuffer));sockaddr_in client;socklen_t client_len;memset(client, 0, sizeof(client));//接收数据的同时监听到客户端的来源ssize_t s recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (sockaddr*)client, client_len);if (s 0) {lg(Waring, recvfrom error, errno: %d, strerror: %s, errno, strerror(errno));continue;}inbuffer[s] 0;//处理数据//创建套接字 用来监听是哪一个客户端string message inbuffer;message func(message, client, clients);//这里的处理使用一个外部的接口//处理完成后 返回发送给客户端BroadCast(message, clients);}}~UdpServer(){if (sockfd_ 0) close(sockfd_); } private:int sockfd_;uint16_t port_;string ip_;bool isrunning_;unordered_mapstring, sockaddr_in clients; //添加哈希表}; #includeUdpServer.hpp #includememory//main.cc主要修改就是Handler函数 我们要通过client里面的ip地址和端口号作为keyclient作为value然后放入哈希表。 同时将message处理一下方便我们观看结果。 string Handler(string message, sockaddr_in client, unordered_mapstring, sockaddr_in clients) {string tmp inet_ntoa(client.sin_addr) to_string(client.sin_port);if (!clients.count(tmp)){clients[tmp] client; cout ip inet_ntoa(client.sin_addr) : port client.sin_port has add in talk room endl;}message [ string(inet_ntoa(client.sin_addr)) : to_string(client.sin_port) ]#: message; return message; }// int main(int argc, char* argv[]) {if (argc ! 2){cout has return endl;return 1;}//uint16_t serverport stoi(argv[1]); unique_ptrUdpServer svr(new UdpServer(serverport));//svr-Init();svr-run(Handler);return 0; } Udpclient #includeiostream using namespace std; #includestring #includesys/types.h #includeLog.hpp #includesys/socket.h #includepthread.h #includearpa/inet.h #includestring.h #includenetinet/in.h Log lg;class ThreadData { public:sockaddr_in server;int sockfd; };//数据接收函数 void* recv_message(void* args) {char buffer[1024];ThreadData* td static_castThreadData*(args); while (true){//接收数据sockaddr_in temp;socklen_t len;string info;ssize_t s recvfrom(td-sockfd, buffer, sizeof(buffer) - 1, 0, (sockaddr*)temp, len);if (s 0){lg(Error, recv error, error: %d, strerror: %s, errno, strerror(errno));continue;}buffer[s] 0;info buffer;cout info endl;}}//数据发送函数 void* send_message(void* args) {ThreadData* td static_castThreadData*(args);string message;while (true){ getline(cin, message); //获取数据//发送数据sendto(td-sockfd, message.c_str(), message.size(), 0, (sockaddr*)td-server, sizeof(td-server));} }int main(int argc, char* argv[]) {if (argc ! 3){cout Client server endl;}//先拿到套接字的参数string serverip argv[1];uint16_t serverport stoi(argv[2]);ThreadData td;//创建套接字与打开网卡memset(td.server, 0, sizeof(td.server));td.server.sin_family AF_INET;td.server.sin_port htons(serverport);td.server.sin_addr.s_addr inet_addr(serverip.c_str());td.sockfd socket(AF_INET, SOCK_DGRAM, 0); //创建文件描述符, 网卡的文件描述符 网络传输就是使用网络文件描述符找到对应的文件内的数据if (td.sockfd 0){lg(Error, client create sockfd error, errno: %d, strerror: %s, errno, strerror(errno));exit(1);}//创建线程 然后运行线程 等待线程pthread_t recv, send;pthread_create(recv, nullptr, recv_message, td);pthread_create(send, nullptr, send_message, td);pthread_join(recv, nullptr);pthread_join(send, nullptr);close(td.sockfd);return 0; }运行结果 最后就是运行结果 运行结果就是下图了 我们已经能够成功的进行两个客户端之间的远程交流 ——————以上就是本节全部内容哦 如果对友友们有帮助的话可以关注博主 方便学习更多知识哦
http://www.dnsts.com.cn/news/154561.html

相关文章:

  • asp建站软件网站怎么伪静态网站
  • wordpress 分类 文章数量网站关键词怎样做优化
  • 比特币做游戏币的网站淮北叶红军
  • 主机怎么做网站二次跳转凯里市黎升网络推广公司
  • 个人网站推广软件wordpress添加百度地图
  • 织梦绿色企业网站模板 苗木企业网站源码 dedecms5.7内核如何建设基层网站
  • .天津网站建设吉林省 网站建设
  • 快站科技免费连接wifi的软件
  • 潜江哪里做网站手机网站这么做链接
  • 做网站图片多少钱网站服务器速度对seo有什么影响?
  • 网站建设-上寻模板公司部门解散
  • 昌图门户网站微信小程序开发需要什么技能
  • 安溪建设局网站为我们搭建了这么好的平台
  • 淄博企业网站建设都兰县建设局交通局网站
  • 妇科医院手机网站源码企业网站名是什么意思
  • 建设部网站危险性较大兼职做一篇微信的网站
  • 白沟网站开发百度登录
  • 徐汇网站推广WordPress清除ID沉余
  • 山东济南建网站公司济源市城乡建设局网站
  • 点了网站域名会跳转上海商用厨房设计
  • 快手里做网站荣耀封面的视频网页版微信登不上去怎么回事
  • 网站兼容9深圳外贸建站
  • 上海中小企业网站友链申请
  • 怎么做公司免费网站网站建立项目步骤
  • 网站刚做怎么做seo优化在线模板制作
  • 应持续抓好二级网站的建设工作太湖县网站建设公司
  • 棋牌网站怎么做优化蓝屏的钙 WordPress
  • 商业网站建设费用服务器租用免费试用
  • 做付费软件网站花式表白网址
  • 中国国际贸易单一窗口网站众筹网站建设方案