Ai
1 Star 0 Fork 0

加法器+/Linux

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
udpServer.hpp 5.51 KB
一键复制 编辑 原始数据 按行查看 历史
加法器+ 提交于 2024-02-04 14:26 +08:00 . udp套接字
#pragma once
#include<iostream>
#include<unordered_map>
#include<functional>
#include<sys/types.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>
#include"log.hpp"
using func_t = std::function<std::string (const std::string&, const std::string&, const uint16_t)>;
extern Log log;
enum
{
SOCKT_ERR = 1,
BIND_ERR
};
uint16_t defaultPort = 8080;
std::string defaultIp = "0.0.0.0";
const int size = 1024;
class udpServer
{
public:
udpServer(const uint16_t &port = defaultPort, const std::string &ip = defaultIp)
:port_(port)
,ip_(ip)
,isrunning_(false)
,sockfd_(0)
{}
void Init()
{
//1.创建套接字
sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd_ < 0)
{
log(Fatal, "socket create error, sockfd: %d", sockfd_);
exit(SOCKT_ERR);
}
log(Info, "socket create success, sockfd: %d", sockfd_);
//2.绑定端口号
struct sockaddr_in local;
//bzero 将指定类型清零
bzero(&local, sizeof(local));
//sin_family 封装的是无符号短整型
local.sin_family = AF_INET; //表明自己类型
//htos 主机序 列转网络序列(大小端)
local.sin_port = htons(port_); //自己的端口号 需保证是网络字节序 因为要发到网络当中
//用户一般使用是点分十进制(192.0.0.1) 需进行转换string->uint23_t
//inet_addr str转网络风格的uint32_t
local.sin_addr.s_addr = inet_addr(ip_.c_str()); //也是在网络中发送,转网络字节序
//local.sin_addr.s_addr = htonl(INADDR_ANY); //任意绑定ip
//此时local还在用户栈上,还未和内核网络套接字关联
//和网络套接字进行绑定
int bd = bind(sockfd_, (const struct sockaddr*)&local, sizeof(local));
if(bd < 0)
{
log(Fatal, "bind error, errno: %d, err string: %s", errno, strerror(errno));
exit(BIND_ERR);
}
log(Info, "bind success");
}
void CheckUser(const struct sockaddr_in &client, const uint16_t &cport, const std::string &cip)
{
auto iter = online_user_.find(cip);
if(iter == online_user_.end())
{
online_user_.insert({cip, client});
std::cout << "add a online user: " << cip << std::endl;
}
}
void Broadcast(const std::string &str, const uint16_t &cport, const std::string &cip)
{
for(auto &user : online_user_)
{
std::string message = "[";
message += cip;
message += ":";
message += std::to_string(cport);
message += "]# ";
message += str;
socklen_t len = sizeof(user.second);
std::cout << "get a message: " << str << std::endl;
sendto(sockfd_, message.c_str(), message.size(), 0, (const struct sockaddr*)&user.second, len);
}
}
void Run(func_t func)
{
isrunning_ = true;
char inbuffer[size];
// 服务器运行 7*24h
while (isrunning_)
{
struct sockaddr_in client;
socklen_t len = sizeof(client);
// 接收数据
// log(Info,"recvfrom already");
ssize_t n = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (struct sockaddr *)&client, &len);
if (n < 0)
{
log(Warning, "recvfrom error, errno: %d, err string: %s", errno, strerror(errno));
continue;
}
//网络转主机
uint16_t clientport = ntohs(client.sin_port);
std::string clientip = inet_ntoa(client.sin_addr);
//检查用户是否存在
CheckUser(client, clientport, clientip);
inbuffer[n] = 0;
std::string s = inbuffer;
Broadcast(s, clientport, clientip);
bzero(inbuffer, sizeof(inbuffer));
}
}
// void Run(func_t func)
// {
// isrunning_ = true;
// char inbuffer[size];
// //服务器运行 7*24h
// while(isrunning_)
// {
// struct sockaddr_in client;
// socklen_t len = sizeof(client);
// //接收数据
// //log(Info,"recvfrom already");
// ssize_t n = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (struct sockaddr*)&client, &len);
// if(n < 0)
// {
// log(Warning, "recvfrom error, errno: %d, err string: %s", errno, strerror(errno));
// continue;
// }
// uint16_t clientport = ntohs(client.sin_port);
// std::string clientip = inet_ntoa(client.sin_addr);
// inbuffer[n] = 0;
// std::string s = inbuffer;
// std::string echo_str = func(s, clientip, clientport);
// // std::string echo_str = "server echo# " + s;
// // std::cout << echo_str << std::endl;
// sendto(sockfd_, echo_str.c_str(), echo_str.size(), 0, (const struct sockaddr*)&client, len);
// }
// }
~udpServer()
{
if(sockfd_ > 0) close(sockfd_);
}
private:
int sockfd_; //网络文件描述符
std::string ip_; //ip
uint16_t port_; //端口号16位 表面服务器进程端口号
bool isrunning_; //检测服务器是否运行
std::unordered_map<std::string, struct sockaddr_in> online_user_;
//online_user_[cip]--
};
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/PYH_2001/linux.git
git@gitee.com:PYH_2001/linux.git
PYH_2001
linux
Linux
master

搜索帮助