当前位置: 首页 > 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;因为我继续…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...