libevent多线程服务器

这个代码没有参考价值,大家不用看了

如果想看看实现的话参考这个吧:https://github.com/Addision/libevent_thread.git

只是windows 环境下, linux 需要自己写个cmake编译

服务器端代码:

 

#include "lib_net.h"
#include "lib_thread.h"
#include "lib_public.h"
#include<event.h>  
#include<event2/util.h>

#define BACKLOG 10
#define MAX_EVENTS 500

char ip[24];
short port;

struct st_listenserv
{
    int sockfd;
    struct event *ev_listen;
    struct event_base *base;
};

struct st_connserv
{
    int clifd;
    struct event_base *base;
    struct event *ev_read;
    struct event *ev_write;
    char buf[1024];
};

void initsocket(struct st_listenserv *listenserv);
void accept_cb(int fd, short events, void *arg);
void read_cb(int fd, short events, void *arg);
void send_cb(int fd, short events, void *arg);
void start_thrd(int fd);
void thrd_readwrite(int sockfd);
void release_read(struct st_connserv *connserv);
void release_write(struct st_connserv *connserv);

int main(int argc, char *argv[])
{
    
    if(argc < 1)
    {
        perror("input server  port");
        return -1;
    }
    memcpy(ip, argv[1], 24);
    port = atoi(argv[2]);
    struct st_listenserv listenserv;
    initsocket(&listenserv);
    listenserv.base = event_base_new();
    listenserv.ev_listen = event_new(listenserv.base, listenserv.sockfd,EV_READ | EV_PERSIST,accept_cb,NULL);
    event_add(listenserv.ev_listen, NULL);
    event_base_dispatch(listenserv.base);
    
}

void initsocket(struct st_listenserv *listenserv)
{
    listenserv->sockfd = lib_tcpsrv_init(ip,port);
    if(listenserv->sockfd < 0)
    {
        perror("server create socket error");
        return;
    }
    if(lib_set_nonblock(listenserv->sockfd) < 0)
    {
        perror("set nonblock error");
        return;
    }
    printf("init socket ok\n");
}

void accept_cb(int fd, short events, void *arg)
{
    struct sockaddr_in cin;
    socklen_t socklen = sizeof(cin);
    int clifd = lib_tcpsrv_accept(fd, &cin);
    if(clifd <0)
    {
        perror("accept error");
    }
    if(lib_set_nonblock(clifd) < 0)
    {
        perror("set nonblock error");
        return;
    }
    printf("new conneciotn [%s:%d]\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
    start_thrd(clifd);
}

void start_thrd(int fd)
{
    pthread_t pid;
    lib_thread_create(&pid, thrd_readwrite, (void*)fd, 1);    
}

void thrd_readwrite(int sockfd)
{

    struct st_connserv connserv;
    connserv.clifd = sockfd;
    connserv.base = event_base_new();
    connserv.ev_read = event_new(connserv.base, connserv.clifd, EV_READ|EV_PERSIST, read_cb, &connserv);
    event_add(connserv.ev_read,NULL);
    event_base_dispatch(connserv.base);
}

void read_cb(int fd, short events, void *arg)
{

    struct st_connserv *conn = (struct st_connserv*)arg;
    int recvlen = lib_tcp_recv(conn->clifd, conn->buf,1024, -1);
    if(recvlen < 0)
    {
        perror("recv error");
        close(conn->clifd);
        release_read(conn);
    }
    printf("recv data:%s\n", conn->buf);
    
    conn->ev_write = event_new(conn->base, conn->clifd, EV_WRITE, send_cb, conn);
    event_add(conn->ev_write, NULL);
}

void send_cb(int fd, short events, void *arg)
{
    struct st_connserv *conn = (struct st_connserv*)arg;
    int sendlen = lib_tcp_send(conn->clifd, conn->buf, 1024);
    if(sendlen < 0)
    {
        perror("send error");
        close(conn->clifd);
        release_write(conn);
    }
}

void release_read(struct st_connserv *connserv)
{
    if(connserv == NULL)
    {
        return;
    }
    event_del(connserv->ev_read);
    event_base_loopexit(connserv->base, NULL);
    if(NULL != connserv->ev_read){
        free(connserv->ev_read);
    }
    event_base_free(connserv->base);
    free(connserv);
    
}

void release_write(struct st_connserv *connserv)
{
    if(connserv != NULL)
    {
        event_del(connserv->ev_write);
        free(connserv->ev_write);
        free(connserv);
    }
}


完整代码地址:https://github.com/Addision/test_libevent_thrd_server

 

简单客户端代码:

 

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 9999
#define IPADDR "127.0.0.1"
int main(int argc, char *argv[])
{
    /*  套接字描述符*/
    int sockfd, numbytes;
	char buf[1024];
    struct sockaddr_in their_addr;  

    if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) 
    {
        perror("socket");
        exit(1);
    }

    their_addr.sin_family = AF_INET;
    /*  网络字节顺序,短整型*/
    their_addr.sin_port = htons(PORT);
    their_addr.sin_addr.s_addr = inet_addr(IPADDR);
    /*  将结构剩下的部分清零*/
    bzero(&(their_addr.sin_zero),8);
    if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("connect");
        exit(1);
    }
	int ret = send(sockfd, "123456", 6,0);
	if(ret > 0)
	{
		printf("send ok\n");
	}
	ret = recv(sockfd, buf, 1024,0);
	if(ret > 0)
	{
		printf("recv data %s\n", buf);
	}
    getchar();
    return 0;
}

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
libevent是一个开源的事件驱动库,可以用于开发高性能的多线服务器架构。它提供了一组API,可以处理各种事件,如网络连接、定时器和信号等。以下是一个基本的libevent线服务器架构的示例: 1. 初始化libevent库:在服务器启动时,首先需要初始化libevent库,并创建一个libevent的上下文对象。 2. 创建监听socket:使用libevent提供的API创建一个监听socket,用于接收客户端的连接请求。 3. 注册事件回调函数:通过使用libevent提供的API,将监听socket的读事件(即有新的连接请求)注册到libevent的事件循环中,并指定对应的回调函数。 4. 创建工作线程池:为了处理多个客户端连接,可以创建一个工作线程池。每个工作线程都负责处理一个或多个客户端连接。 5. 接收客户端连接:当有新的客户端连接请求到达时,libevent会触发注册的回调函数。在回调函数中,可以接受客户端连接,创建新的套接字,并将其注册到libevent的事件循环中。 6. 分发工作:当新的客户端连接被接受后,可以选择将其分发给工作线程池中的某个线程进行处理。可以使用线程池管理库或手动实现线程池。 7. 处理客户端请求:在工作线程中,可以通过libevent的事件循环处理客户端的读写事件。可以注册读事件来接收客户端发送的数据,注册写事件来发送响应数据。 8. 关闭连接:当客户端断开连接或发生错误时,需要关闭对应的套接字,并从libevent的事件循环中移除。 以上是一个简单的libevent线服务器架构的基本步骤。实际应用中,还可以结合其他技术和设计模式来实现更复杂的功能和性能优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值