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

基于libevent的tcp服务器

libevent使用教程_evutil_make_socket_nonblocking_易方达蓝筹的博客-CSDN博客

一、准备

centos7下安装libevent库

yum install libevent
yum install -y libevent-devel

二、代码

server.cpp

/**
You need libevent2 to compile this piece of code
Please see: http://libevent.org/
Or you can simply run this command to install on Mac: brew install libevent
Cmd to compile this piece of code: g++ LibeventQuickStartServer.c  -o  LibeventQuickStartServer /usr/local/lib/libevent.a
**/
#include<stdio.h>  
#include<string.h>  
#include<errno.h>  #include<unistd.h>  
#include<event.h>void accept_cb(int fd, short events, void* arg);
void socket_read_cb(int fd, short events, void* arg);int tcp_server_init(int port, int listen_num);int main(int argc, char const *argv[])
{/* code */int listener = tcp_server_init(9999, 10);if (listener == -1){perror("tcp_server_init error");return -1;}struct event_base* base = event_base_new();// 监听客户端请求链接事件struct event* ev_listen = event_new(base, listener, EV_READ | EV_PERSIST, accept_cb, base);printf("wait for client connect\n");event_add(ev_listen, NULL);event_base_dispatch(base);return 0;
}void accept_cb(int fd, short events, void* arg)
{evutil_socket_t sockfd;struct sockaddr_in client;socklen_t len = sizeof(client);sockfd = ::accept(fd, (struct sockaddr*)&client, &len);evutil_make_socket_nonblocking(sockfd);printf("accept a client %d\n", sockfd);struct event_base* base = (event_base*)arg;//动态创建一个event结构体,并将其作为回调参数传递给struct event* ev = event_new(NULL, -1, 0, NULL, NULL);event_assign(ev, base, sockfd, EV_READ | EV_PERSIST, socket_read_cb, (void*)ev);event_add(ev, NULL);
}void socket_read_cb(int fd, short events, void* arg)
{char msg[4096];struct event* ev = (struct event*)arg;int len = read(fd, msg, sizeof(msg) - 1);if(len <= 0){printf("some error happen when read\n");event_free(ev);close(fd);return;}msg[len] = '\0';printf("recv the client msg : %s\n", msg);char reply_msg[4096] = "I have received the msg: ";strcat(reply_msg + strlen(reply_msg), msg);write(fd, reply_msg, strlen(reply_msg));
}typedef struct sockaddr SA;  
int tcp_server_init(int port, int listen_num)  
{  int errno_save;  evutil_socket_t listener;  listener = ::socket(AF_INET, SOCK_STREAM, 0);  if( listener == -1 )  return -1;  //允许多次绑定同一个地址。要用在socket和bind之间  evutil_make_listen_socket_reuseable(listener);  struct sockaddr_in sin;  sin.sin_family = AF_INET;  sin.sin_addr.s_addr = 0;  sin.sin_port = htons(port);  if( ::bind(listener, (SA*)&sin, sizeof(sin)) < 0 )  goto error;  if( ::listen(listener, listen_num) < 0)  goto error;  //跨平台统一接口,将套接字设置为非阻塞状态  evutil_make_socket_nonblocking(listener);  return listener;  error:  errno_save = errno;  evutil_closesocket(listener);  errno = errno_save;  return -1;  
}  

 client.cpp


/**
You need libevent2 to compile this piece of code
Please see: http://libevent.org/
Or you can simply run this command to install on Mac: brew install libevent
Cmd to compile this piece of code: g++ LibeventQuickStartClient.c -o LibeventQuickStartClient /usr/local/lib/libevent.a
**/
#include<sys/types.h>  
#include<sys/socket.h>  
#include<netinet/in.h>  
#include<arpa/inet.h>  
#include<errno.h>  
#include<unistd.h>  #include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  #include<event.h>  
#include<event2/util.h>  int tcp_connect_server(const char* server_ip, int port);  void cmd_msg_cb(int fd, short events, void* arg);  
void socket_read_cb(int fd, short events, void *arg);  int main(int argc, char** argv)  
{    //两个参数依次是服务器端的IP地址、端口号  int sockfd = tcp_connect_server("127.0.0.1", 9999);  if( sockfd == -1)  {  perror("tcp_connect error ");  return -1;  }  printf("connect to server successful\n");  struct event_base* base = event_base_new();  struct event *ev_sockfd = event_new(base, sockfd,  EV_READ | EV_PERSIST,  socket_read_cb, NULL);  event_add(ev_sockfd, NULL);  //监听终端输入事件  struct event* ev_cmd = event_new(base, STDIN_FILENO,  EV_READ | EV_PERSIST, cmd_msg_cb,  (void*)&sockfd);  event_add(ev_cmd, NULL);  event_base_dispatch(base);  printf("finished \n");  return 0;  
}  void cmd_msg_cb(int fd, short events, void* arg)  
{  char msg[1024];  int ret = read(fd, msg, sizeof(msg));  if( ret <= 0 )  {  perror("read fail ");  exit(1);  }  int sockfd = *((int*)arg);  //把终端的消息发送给服务器端  //为了简单起见,不考虑写一半数据的情况  write(sockfd, msg, ret);  
}  void socket_read_cb(int fd, short events, void *arg)  
{  char msg[1024];  //为了简单起见,不考虑读一半数据的情况  int len = read(fd, msg, sizeof(msg)-1);  if( len <= 0 )  {  perror("read fail ");  exit(1);  }  msg[len] = '\0';  printf("get respond from server: %s \n", msg);  
}  typedef struct sockaddr SA;  
int tcp_connect_server(const char* server_ip, int port)  
{  int sockfd, status, save_errno;  struct sockaddr_in server_addr;  memset(&server_addr, 0, sizeof(server_addr) );  server_addr.sin_family = AF_INET;  server_addr.sin_port = htons(port);  status = inet_aton(server_ip, &server_addr.sin_addr);  if( status == 0 ) //the server_ip is not valid value  {  errno = EINVAL;  return -1;  }  sockfd = ::socket(PF_INET, SOCK_STREAM, 0);  if( sockfd == -1 )  return sockfd;  status = ::connect(sockfd, (SA*)&server_addr, sizeof(server_addr) );  if( status == -1 )  {  save_errno = errno;  ::close(sockfd);  errno = save_errno; //the close may be error  return -1;  }  evutil_make_socket_nonblocking(sockfd);  return sockfd;  
}  

g++ client.cpp -std=c++11 -o client -levent

相关文章:

基于libevent的tcp服务器

libevent使用教程_evutil_make_socket_nonblocking_易方达蓝筹的博客-CSDN博客 一、准备 centos7下安装libevent库 yum install libevent yum install -y libevent-devel 二、代码 server.cpp /** You need libevent2 to compile this piece of code Please see: http://li…...

【TypeScript】tsc -v 报错 —— 在此系统上禁止运行脚本

在 VS Code 终端中执行 tsc -v &#xff0c;报错 —— 在此系统上禁止运行脚本 然后 windows x &#xff0c;打开终端管理员&#xff0c;出现同样的问题 解决方法&#xff1a; 终端&#xff08;管理员&#xff09;执行以下命令&#xff1a; 出现 RemoteSigned 则代表更改成功…...

【C++】STL---list

STL---list 一、list 的介绍二、list 的模拟实现1. list 节点类2. list 迭代器类&#xff08;1&#xff09;前置&#xff08;2&#xff09;后置&#xff08;3&#xff09;前置- -、后置- -&#xff08;4&#xff09;! 和 运算符重载&#xff08;5&#xff09;* 解引用重载 和 …...

六、分组背包

六、分组背包 题记算法题目代码 题记 一个旅行者有一个最多能装V公斤的背包和有N件物品&#xff0c;它们的重量分别是W[1]&#xff0c;W[2]&#xff0c;…,W[n]&#xff0c;它们的价值分别为C[1],C[2],…,C[n]。这些物品被划分为若干组&#xff0c;每组中的物品互相冲突&#…...

LangChain入门:构建LLM驱动的应用程序的初学者指南

LangChain & DemoGPT 一、介绍 你有没有想过如何使用大型语言模型&#xff08;LLM&#xff09;构建强大的应用程序&#xff1f;或者&#xff0c;也许您正在寻找一种简化的方式来开发这些应用程序&#xff1f;那么你来对地方了&#xff01;本指南将向您介绍LangChain&#x…...

gitlab修改远程仓库地址

目录 背景&#xff1a; 解决&#xff1a; 1.删除本地仓库关联的远程地址&#xff0c;添加新的远程仓库地址 2.直接修改本地仓库关联的远程仓库地址 3.打开.git隐藏文件修改远程仓库地址 4.拉取代码报错(git host key verification failed) 背景&#xff1a; 公司搬家&#…...

VB+SQL自动点歌系统设计与实现

摘 要 随着社会的发展,人类的进步,21世纪人们的生活的水平有所提高,为了满足人们对生活的需要,丰富业余生活,就需要有一些娱乐的设施来弥补这些空缺,所以开发了自动点歌系统。 论文详细论述了系统总体设计思想、数据库设计以及功能模块设计等,给出了自动点歌系统一般流程…...

设计模式之适配器模式(Adapter)的C++实现

1、适配器模式的提出 在软件功能开发中&#xff0c;由于使用环境的改变&#xff0c;之前一些类的旧接口放在新环境的功能模块中不再适用。如何使旧接口能适用于新的环境&#xff1f;适配器可以解决此类问题。适配器模式&#xff1a;通过增加一个适配器类&#xff0c;在适配器接…...

C#系统锁屏事件例子 - 开源研究系列文章

今天有个网友问了个关于操作系统锁屏的问题。 我们知道&#xff0c;操作系统是基于消息和事件处理的&#xff0c;所以我们只要找到该操作系统锁屏和解屏的那个事件&#xff0c;然后在事件里进行处理即可。下面是例子介绍。 1、 项目目录&#xff1b; 下面是项目目录&#xff1a…...

R语言实现免疫浸润分析(2)

原始数据承接免疫浸润分析&#xff08;1&#xff09;&#xff0c;下面展示免疫浸润结果&#xff1a; #直接使用IOBR包内的cell_bar_plot pic<-cell_bar_plot(input quantiseq_immo_de[1:20,], title "quanTiseq Cell Fraction") #使用ggplot2 library(ggplot2)…...

系统架构设计师-信息安全技术(2)

目录 一、安全架构概述 1、信息安全所面临的威胁 二、安全模型 1、安全模型的分类 2、BLP模型 3、Biba 模型 4、Chinese Wall模型 三、信息安全整体架构设计 1、WPDRRC模型 2、各模型的安全防范功能 四、网络安全体系架构设计 1、开放系统互联安全体系结构 2、安全服务与安…...

STM32F4X-GPIO输入功能使用

STM32F4 GPIO输入模式配置 上一节讲GPIO的时候说到了将GPIO设置成输出模式&#xff0c;并通过将GPIO的电平拉高拉低控制LED灯的例程。GPIO除了用作输出功能之外&#xff0c;还可以用作输入功能。最常用的就是检测按键的输入电平。 硬件设计 本章的硬件是基于正点原子的探索者…...

Jenkins-CICD-python/Java包升级与回退

Jenkins- CICD流水线 python/Java代码升级与回退 1、执行思路 1.1、代码升级 jenkins上点击 upgrade和 代码版本号 --${tag} jenkins 推送 代码 和 执行脚本 到目标服务器/opt目录下 执行命令 sh run.sh 代码名称 版本号 upgrade 版本号 来自jenkins的 构建参数中的 标签…...

模糊测试面面观 | 模糊测试工具知多少

自1988年威斯康星大学的Barton Miller首次提出模糊测试这一概念以来&#xff0c;模糊测试领域经历了持续长久发展。模糊测试作为一种软件测试方法&#xff0c;旨在通过向程序输入模糊、随机、异常的数据&#xff0c;探测和发现潜在的漏洞和错误。这种方法备受安全研究人员的青睐…...

esp8266+电压检测模块检测电池电压

该模块5v时输出1v&#xff0c;因esp8266 ADC引脚(A0)支持电压范围是0v-1v&#xff0c;所以该方案仅支持0-5v电压检测 接线&#xff1a; - 接 esp8266GND 可不接 S 接 ADC esp8266 为 A0 VCC 被检测直流电 GND 被检测直流电- #include <Wire.h>const int adcPin A0; // …...

MongoDB增删改查操作

数据库操作&#xff1a; 在MongoDB中&#xff0c;文档集合存在数据库中。 要选择使用的数据库&#xff0c;请在mongo shell程序中发出 use <db> 语句 // 查看有哪些数据库 show dbs;// 如果数据库不存在&#xff0c;则创建并切换到该数据库&#xff0c;存在则直接切换到…...

Python | Package | Python的三种包安装方式(pip/whl/tar.gz)

文章目录 PIP 安装与卸载Source 安装与卸载Whell 安装与卸载 PIP 安装与卸载 pip install xxx pip install xxxversion_numberpip install captcha pip install captcha0.4# XXX/anaconda3/envs/py373/lib/python3.7/site-packages pip uninstall captchaSource 安装与卸载 p…...

1. 微信小程序开发环境搭建

下载 微信的小程序开发需要使用到微信开发者工具&#xff0c;通过https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html可以下载 下载完成后 安装...

Redis五大基本数据类型及其使用场景

文章目录 **一 什么是NoSQL&#xff1f;****二 redis是什么&#xff1f;****三 redis五大基本类型**1 String&#xff08;字符串&#xff09;**应用场景** 2 List&#xff08;列表&#xff09;**应用场景** 3 Set&#xff08;集合&#xff09;4 sorted set&#xff08;有序集合…...

优于立方复杂度的 Rust 中矩阵乘法

优于立方复杂度的 Rust 中矩阵乘法 迈克克维特 跟随 发表于 更好的编程 6 分钟阅读 7月 <> 143 中途&#xff1a;三次矩阵乘法 一、说明 几年前&#xff0c;我在 C 年编写了 Strassen 矩阵乘法算法的实现&#xff0c;最近在 Rust 中重新实现了它&#xff0c;因为我继续…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...