如何创建基于udp的客户端和服务端

1.先创建好udpServer.hpp、udpServer.cc、udpClient.hpp、udpClient.cc的框架。

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
#include"userManager"
#include<pthread.h>
using namespace std;
const static string defaultip = "0.0.0.0";
// typedef function<void(int,string,uint16_t,string)> func_t;
typedef void (*func_t)(int,string,uint16_t,string);
class udpServer
{
public:udpServer(uint16_t port,func_t callback) : _port(port),_callback(callback){}void init(){}void start(){}~udpServer() {}private:int _fd;uint16_t _port;string _ip;func_t _callback;
};
#include "udpServer.hpp"
#include <memory>
#include<fstream>
using namespace std;
int main(int argc, char *argv[])
{if (argc != 2){cout << "输入错误,请重新输入" << endl;}uint16_t port = atoi(argv[1]);unique_ptr<udpServer> server(new udpServer(port, callback));server->init();server->start();return 0;
}
#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <pthread.h>
using namespace std;
class udpClient
{public:udpClient(string serverip,uint16_t serverport):_serverip(serverip),_serverport(serverport),_fd(-1){}void init(){}void start(){}~udpClient(){}private:int _fd;string _serverip;uint16_t _serverport;pthread_t reader;//这是后期需要的,看不懂接着往下看就可以
};
#include"udpClient.hpp"
#include<memory>
using namespace std;int main(int argc,char* argv[]){if(argc!=3){cout<<"输入错误,请重新输入"<<endl;}uint16_t port = atoi(argv[2]);string ip = argv[1];unique_ptr<udpClient> client(new udpClient(ip,port));client->init();client->start();
}

2.init初始化。

 //udpServer.hpp
void init(){// 创建套接字返回fd_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket error:" << errno << ":" << strerror(errno) << endl;exit(1);}// 将fd和ip,port进行绑定struct sockaddr_in sock;sock.sin_family = AF_INET;sock.sin_port = htons(_port);sock.sin_addr.s_addr = INADDR_ANY;int n = bind(_fd, (struct sockaddr *)&sock, sizeof(sock));if (n == -1){cerr << "bind error:" << errno << ":" << strerror(errno) << endl;exit(2);}}
//udpClient.hpp 
void init(){_fd = socket(AF_INET,SOCK_DGRAM,0);if(_fd == -1){cout<<"socket err:"<<errno<<":"<<strerror(errno)<<endl;exit(1);}}

3.start发送、接收数据。

 //udpServer.cc
void callback(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());messages = "服务端的输出结果:"+messages;sendto(fd, messages.c_str(), messages.size(), 0,(struct sockaddr *)&client, len);}//udpServer.hpp
void start(){char buffer[1024];size_t len = sizeof(buffer);char writer[1024];struct sockaddr_in clientsock;socklen_t clientlen = sizeof(clientsock);while (1)//服务器的本质就是一个死循环{size_t n = recvfrom(_fd, buffer, len-1, 0, (struct sockaddr *)&clientsock, &clientlen);if (n > 0){buffer[n]=0;string ip = inet_ntoa(clientsock.sin_addr); // uint32_t->stringuint16_t port = ntohs(clientsock.sin_port);string messages = buffer;cout << ip << "[" << port << "]" << "#" << messages << endl;_callback(_fd,ip,port,messages);}}}
 //udpCLient.hpp
static void* readroutine(void* args){pthread_detach(pthread_self());udpClient* c = static_cast<udpClient*>(args);sockaddr_in server;socklen_t serverlen = sizeof(server);while(1){char buffer[1024];int len = sizeof(buffer);size_t n = recvfrom(c->_fd, buffer, len-1, 0, (struct sockaddr *)&server, &serverlen);if (n > 0){buffer[n]=0;cout <<buffer << endl;}}}void start(){pthread_create(&reader,NULL,readroutine,(void*)this);char buffer[1024];struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(_serverport);serveraddr.sin_addr.s_addr = inet_addr(_serverip.c_str());while(1){cin>>buffer;ssize_t n = sendto(_fd,buffer,sizeof(buffer),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));if(n == -1){cout<<"sendto err:"<<errno<<":"<<strerror(errno)<<endl;}}}

完整代码:

udpClient.cc

#include"udpClient.hpp"
#include<memory>
using namespace std;int main(int argc,char* argv[]){if(argc!=3){cout<<"输入错误,请重新输入"<<endl;}uint16_t port = atoi(argv[2]);string ip = argv[1];unique_ptr<udpClient> client(new udpClient(ip,port));client->init();client->start();
}

 udpClient.hpp

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <pthread.h>
using namespace std;
class udpClient
{public:udpClient(string serverip,uint16_t serverport):_serverip(serverip),_serverport(serverport),_fd(-1){}void init(){_fd = socket(AF_INET,SOCK_DGRAM,0);if(_fd == -1){cout<<"socket err:"<<errno<<":"<<strerror(errno)<<endl;exit(1);}}static void* readroutine(void* args){pthread_detach(pthread_self());udpClient* c = static_cast<udpClient*>(args);sockaddr_in server;socklen_t serverlen = sizeof(server);while(1){char buffer[1024];int len = sizeof(buffer);size_t n = recvfrom(c->_fd, buffer, len-1, 0, (struct sockaddr *)&server, &serverlen);if (n > 0){buffer[n]=0;cout <<buffer << endl;}}}void start(){pthread_create(&reader,NULL,readroutine,(void*)this);char buffer[1024];struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(_serverport);serveraddr.sin_addr.s_addr = inet_addr(_serverip.c_str());while(1){cin>>buffer;ssize_t n = sendto(_fd,buffer,sizeof(buffer),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));if(n == -1){cout<<"sendto err:"<<errno<<":"<<strerror(errno)<<endl;}}}~udpClient(){}private:int _fd;string _serverip;uint16_t _serverport;pthread_t reader;
};

 udpServer.cc

#include "udpServer.hpp"
#include <memory>
#include<fstream>
using namespace std;
// 处理方式1:翻译软件
unordered_map<string, string> dictmap;
void to_map(string messages);
// 1.打开文件,按行读取
void openfile()
{ifstream in;in.open("dict.txt",std::ios::binary);if(in.is_open()){std::string line;while(getline(in,line)){to_map(line);}}
}
// 2.按行存到map中
void to_map(string messages)
{size_t pos = messages.find(":");dictmap.insert(make_pair(messages.substr(0, pos), messages.substr(pos + 1)));
}
// 3.接收传来的message并通过map查询
void translate(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());if (dictmap.find(messages) != dictmap.end()){cout<<"messages:"<<dictmap[messages].c_str()<<endl;sendto(fd, dictmap[messages].c_str(), dictmap[messages].size(), 0,(struct sockaddr *)&client, len);}else{string mes = "无结果";sendto(fd, mes.c_str(), mes.size(),0, (struct sockaddr *)&client, len);}
}
// 4.test测试文件有没有加载成功
void printdict()
{for (auto e : dictmap){cout << e.first << ":" << e.second << endl;}
}
// 处理方式2:群聊
onlineUser onlineuser;
void group_chat(int fd, string ip, uint16_t port, string messages)
{// 将客户端的信息传进来onlineuser.addOnlineUser(ip, port);onlineuser.broadcastMessage(fd, ip, port, messages);
}
// 处理方式3:最简单版本收到什么原样返回
void callback(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());messages = "服务端的输出结果:"+messages;sendto(fd, messages.c_str(), messages.size(), 0,(struct sockaddr *)&client, len);}
int main(int argc, char *argv[])
{if (argc != 2){cout << "输入错误,请重新输入" << endl;}uint16_t port = atoi(argv[1]);//openfile();//printdict();unique_ptr<udpServer> server(new udpServer(port, callback));server->init();server->start();return 0;
}

 udpServer.hpp

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
#include"userManager"
#include<pthread.h>
using namespace std;const static string defaultip = "0.0.0.0";
// typedef function<void(int,string,uint16_t,string)> func_t;
typedef void (*func_t)(int,string,uint16_t,string);
class udpServer
{
public:udpServer(uint16_t port,func_t callback) : _port(port),_callback(callback){}void init(){// 创建套接字返回fd_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket error:" << errno << ":" << strerror(errno) << endl;exit(1);}// 将fd和ip,port进行绑定struct sockaddr_in sock;sock.sin_family = AF_INET;sock.sin_port = htons(_port);sock.sin_addr.s_addr = INADDR_ANY;int n = bind(_fd, (struct sockaddr *)&sock, sizeof(sock));if (n == -1){cerr << "bind error:" << errno << ":" << strerror(errno) << endl;exit(2);}}void start(){char buffer[1024];size_t len = sizeof(buffer);char writer[1024];struct sockaddr_in clientsock;socklen_t clientlen = sizeof(clientsock);while (1){size_t n = recvfrom(_fd, buffer, len-1, 0, (struct sockaddr *)&clientsock, &clientlen);if (n > 0){buffer[n]=0;string ip = inet_ntoa(clientsock.sin_addr); // uint32_t->stringuint16_t port = ntohs(clientsock.sin_port);string messages = buffer;cout << ip << "[" << port << "]" << "#" << messages << endl;_callback(_fd,ip,port,messages);}}}~udpServer() {}private:int _fd;uint16_t _port;string _ip;pthread_t writer;func_t _callback;
};

 makefile

cc=g++
.PHONY:all
all:udpClient udpServerudpClient:udpClient.cc$(cc) -o $@ $^ -std=c++11 -lpthread
udpServer:udpServer.cc$(cc) -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f udpClient udpServer

以下是拓展的代码:

群聊:userManager

#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
using namespace std;
class User
{
public:User(std::string ip, uint16_t port) : _ip(ip), _port(port){}~User(){}std::string _ip;int16_t _port;
};
class onlineUser
{
public:onlineUser() {}~onlineUser() {}void addOnlineUser(std::string ip, uint16_t port){string id = ip + "[" + std::to_string(port) + "]#";onUser.insert(make_pair(id, User(ip, port)));}void offOnlineUser(std::string ip, uint16_t port){string id = ip + "[" + std::to_string(port) + "]#";onUser.erase(id);}void broadcastMessage(int sockfd, const string &ip, const int16_t &port, const string &messages){string id = ip + "[" + std::to_string(port) + "]#";for (auto &user : onUser){if (user.first != id){sockaddr_in usersock;usersock.sin_family = AF_INET;usersock.sin_port = htons(user.second._port);usersock.sin_addr.s_addr = inet_addr(user.second._ip.c_str());string sendmessage = id + messages;sendto(sockfd, sendmessage.c_str(), sendmessage.size(), 0, (struct sockaddr *)&usersock, sizeof(usersock));}}}private:unordered_map<string, User> onUser;
};

 字典:dict.txt

hello:你好
why:为什么
so:所以
then:然后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62587.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【上线文档】系统上线方案模板,计算机系统上线保障计划,系统运维信息系统运行保障方案,系统上线方案模板(Word原件)

一、项目背景和目标 二、项目需求分析 2.1 功能需求 2.2 非功能需求 三、系统设计 3.1 系统架构设计 3.2 数据库设计 3.3 接口设计 3.4 用户界面设计 四、系统开发 4.1 开发环境搭建 4.2 业务逻辑开发 4.3 数据库实现 4.4 接口实现 4.5 用户界面实现 五、系统测…

大模型应用的数字能源数据集

除了尚须时日的量子计算解决算力效率和能源问题&#xff0c;以及正在路上的超越transformer的全新模型架构外&#xff0c;无疑是“数据集”&#xff0c;准确讲是“高质量大规模多样性的数据集”。数据集是大模型发展的核心要素之一&#xff0c;是大计算的标的物&#xff0c;是实…

【OpenCV】图像转换

理论 傅立叶变换用于分析各种滤波器的频率特性。对于图像&#xff0c;使用 2D离散傅里叶变换&#xff08;DFT&#xff09; 查找频域。快速算法称为 快速傅立叶变换&#xff08;FFT&#xff09; 用于计算DFT。 Numpy中的傅立叶变换 首先&#xff0c;我们将看到如何使用Numpy查…

如何使用Java编写Jmeter函数

Jmeter 自带有各种功能丰富的函数&#xff0c;可以帮助我们进行测试&#xff0c;但有时候提供的这些函数并不能满足我们的要求&#xff0c;这时候就需要我们自己来编写一个自定义的函数了。例如我们在测试时&#xff0c;有时候需要填入当前的时间&#xff0c;虽然我们可以使用p…

【2024版】最新kali linux入门及常用简单工具介绍(非常详细)从零基础入门到精通,看完这一篇就够了

前言 相信很多同学了解到和学习网络安全的时候都听过kali系统&#xff0c;大家都称之为黑客最喜爱的系统&#xff0c;那么什么是kali&#xff0c;初学者用kali能做些什么&#xff0c;大白我将在本文中做详细的介绍&#xff1a; 一、kali linux是什么&#xff1f; Kali Linux…

使用 electron 把 vue 项目打包成客户端

1. 新建一个Vue项目 新建一个vue项目&#xff0c;或者在已经写好的vue项目上操作 2. 安装依赖包 需要安装的包有2个 electron electron-builder 安装失败的&#xff0c;可看另外一篇解决方法https://blog.csdn.net/Anorry/article/details/144061069?spm1001.2014.3001.5501 3…

六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序

本章讲述数据结构中的六大排序算法 欢迎大佬们踊跃讨论&#xff0c;感谢大家支持&#xff01; 我的博客主页链接 六大排序算法 一.插入排序1.1 直接插入排序1.2 希尔排序 二.选择排序2.1 单向选择排序2.2双向选择排序2.3 堆排序 三.交换排序3.1 冒泡排序3.2 快速排序3.2.1 Hoa…

el-table手动触发懒加载

二次修改了一下&#xff0c;确保点击某一单元格格元素触发 // 隐藏懒加载箭头后手动触发懒加载 expandRows(scope){scope.row.isExpanded !scope.row.isExpanded // 切换展开状态let isExpanded scope.row.isExpandedconst { table: { toggleRowExpansion, store }} this.$r…

【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

threejs相机辅助对象cameraHelper

为指定相机创建一个辅助对象&#xff0c;显示这个相机的视锥。 想要在场景里面显示相机的视锥&#xff0c;需要创建两个相机。 举个例子&#xff0c;场景中有个相机A&#xff0c;想要显示相机A的视锥&#xff0c;那么需要一个相机B&#xff0c;把B放在A的后面&#xff0c;两个…

反向代理-缓存篇

文章目录 强缓存一、Expires(http1.0 规范)二、cache-control(http1.1 出现的 header 信息)Cache-Control 的常用选项Cache-Control 常用选项的选择三、弊端协商缓存一、ETag二、If-None-Match三、Last-modified四、If-Modified-Since浏览器的三种刷新方式静态资源部署策略…

健康管理系统(Koa+Vue3)

系统界面(源码末尾获取) 系统技术 Vue3 Koa Nodejs Html Css Js ....... 系统介绍 系统比较简单,轻轻松松面对结业课堂作业.采用的是基于nodejs开发的Koa框架作为后端,采用Vue框架作为前端,完成快速开发和界面展示. 系统获取 啊啊啊宝/KoaVue3https://gitee.com/ah-ah-b…

数据清洗代码:缺失值,异常值,离群值Matlab处理

目录 基本介绍程序设计参考资料基本介绍 一、过程概述 本过程适用于处理SCADA系统采集到的数据,以及具有类似需求的数据集。处理步骤包括缺失值处理、异常值处理和离群值处理,旨在提升数据质量,增强数据的相关性,同时保持数据的原始特征和随机性。 二、缺失值处理 对于SC…

Leetcode 每日一题 202.快乐数

目录 题意 算法思路 过题图片 算法实现 代码解析 复杂度分析 题目链接 结论 题意 判断正整数 n 是不是快乐数。 快乐数定义&#xff1a; &#xff08;1&#xff09;每次将正整数替换为它每个位置上的数字的平方和。 &#xff08;2&#xff09;重复这个过程直到这个数…

【鸿蒙生态崛起】开发者如何把握机遇,应对挑战,打造卓越应用体验?

文章目录 每日一句正能量前言鸿蒙简析鸿蒙生态的认知和了解鸿蒙生态的崛起分析 鸿蒙生态下开发时遇到的挑战开发工具不完善技术难度生态竞争抓住机遇、应对挑战 鸿蒙生态未来的发展趋势1. 全场景智慧生活的推动者2. 技术创新的引领者3. 开放合作的倡导者对鸿蒙生态和开发者的建…

Nignx部署Java服务测试使用的Spring Boot项目Demo

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

文本域设置高度 加上文字限制并show出来:

文本域设置高度 :rows"4" 加上文字限制并show出来&#xff1a; maxlength"30" show-word-limit 效果: <el-form-item label"产品备注" prop"remark"><el-input v-model"form.remark" type"textarea"…

区块链软件系统海外宣发:全球化市场中的策略与实施

随着区块链技术的快速发展&#xff0c;越来越多的区块链软件系统进入全球市场&#xff0c;涉及加密货币、智能合约、去中心化金融&#xff08;DeFi&#xff09;、供应链管理等多个行业应用。为了在激烈的竞争中脱颖而出&#xff0c;区块链软件系统不仅需要具备卓越的技术能力&a…

springboot413福泰轴承股份有限公司进销存系统(论文+源码)_kaic

摘 要 使用旧方法对福泰轴承股份有限公司进销存系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在福泰轴承股份有限公司进销存系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不…

配置中心 选型 : Apollo Vs. Nacos Vs. spring cloud config

为什么我们需要一个微服务配置中心&#xff1f; 首先&#xff0c;我们可以想象下&#xff0c;如果没有配置中心&#xff0c;我们的项目可能是这样的&#xff1a;不同环境的配置文件都放在项目里面&#xff0c;部署时可以通过启动参数来指定使用哪个环境的配置。 这种方式有两…