Libevent例子(二)
2023-03-07 09:41:29 时间
服务端
#include<netinet/in.h> #include<stdio.h> #include<string.h> #include<event.h> #include<event2/listener.h> #include<event2/bufferevent.h> #include<event2/thread.h> void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sock, int socklen, void *arg); void socket_read_cb(struct bufferevent *bev, void *arg); void socket_event_cb(struct bufferevent *bev, short events, void *arg); int main() { //evthread_use_pthreads();//enable threads struct sockaddr_in sin; memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_port = htons(18001); struct event_base *base = event_base_new(); struct evconnlistener *listener = evconnlistener_new_bind( base, listener_cb, base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 10, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)); event_base_dispatch(base); evconnlistener_free(listener); event_base_free(base); return 0; } //一个新客户端连接上服务器了 //当此函数被调用时,libevent已经帮我们accept了这个客户端。该客户端的 //文件描述符为fd void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sock, int socklen, void *arg) { printf("accept a client %d\n", fd); struct event_base *base = (struct event_base *) arg; //为这个客户端分配一个bufferevent struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, socket_read_cb, NULL, socket_event_cb, NULL); bufferevent_enable(bev, EV_READ | EV_PERSIST); } void socket_read_cb(struct bufferevent *bev, void *arg) { char msg[4096]; size_t len = bufferevent_read(bev, msg, sizeof(msg) - 1); msg[len] = '\0'; printf("server read the data %s\n", msg); char reply[] = "I has read your data"; bufferevent_write(bev, reply, strlen(reply)); } void socket_event_cb(struct bufferevent *bev, short events, void *arg) { if (events & BEV_EVENT_EOF) { printf("connection closed\n"); } else if (events & BEV_EVENT_ERROR) { printf("some other error\n"); } //这将自动close套接字和free读写缓冲区 bufferevent_free(bev); }
客户端
#include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<stdio.h> #include<string.h> #include<stdlib.h> #include<event.h> #include<event2/bufferevent.h> #include<event2/buffer.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 server_msg_cb(struct bufferevent *bev, void *arg); void event_cb(struct bufferevent *bev, short event, void *arg); int main(int argc, char **argv) { if (argc < 3) { //两个参数依次是服务器端的IP地址、端口号 printf("please input 2 parameter\n"); return -1; } struct event_base *base = event_base_new(); struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); //监听终端输入事件 struct event *ev_cmd = event_new( base, STDIN_FILENO, EV_READ | EV_PERSIST, cmd_msg_cb, (void *) bev); event_add(ev_cmd, NULL); struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1], &server_addr.sin_addr); bufferevent_socket_connect( bev, (struct sockaddr *) &server_addr, sizeof(server_addr)); bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void *) ev_cmd); bufferevent_enable(bev, EV_READ | EV_PERSIST); 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); } struct bufferevent *bev = (struct bufferevent *) arg; //把终端的消息发送给服务器端 bufferevent_write(bev, msg, ret); } void server_msg_cb(struct bufferevent *bev, void *arg) { char msg[1024]; size_t len = bufferevent_read(bev, msg, sizeof(msg)); msg[len] = '\0'; printf("recv %s from server\n", msg); } void event_cb(struct bufferevent *bev, short event, void *arg) { if (event & BEV_EVENT_EOF) { printf("connection closed\n"); } else if (event & BEV_EVENT_ERROR) { printf("some other error\n"); } else if (event & BEV_EVENT_CONNECTED) { printf("the client has connected to server\n"); return; } //这将自动close套接字和free读写缓冲区 bufferevent_free(bev); struct event *ev = (struct event *) arg; event_free(ev); }
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的