Due to the recent epoll version of the server, there have been some strange problems, and it is necessary to use libev to go online quickly. Here, we will record a simple use case. There may be some bugs in the code. This code is not a code that runs online, but it is already well-organized. If you have any questions, please discuss it. 
 
 
 
 
#include <ev.h>
#include <stdio.h>
#include <netinet/in.h>
#include<stdlib.h>
#include <string.h>
  
#define PORT 57789
#define BUFFER_SIZE 2048
#define MAX_ALLOWED_CLIENT 10240
  
Struct ev_io *libevlist[MAX_ALLOWED_CLIENT] = {NULL};
  
Void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
  
Void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
  
Void timer_beat(struct ev_loop *loop, struct ev_timer *watcher, int revents);
  
Int freelibev(struct ev_loop *loop, int fd);
  
  
Int main()
{
    Struct ev_loop *loop=ev_default_loop(0);
    Int sd;
    Struct sockaddr_in addr;
    Int addr_len = sizeof(addr);
      
    / / Create an io watcher and a timer watcher
    Struct ev_io socket_accept;
    Struct ev_timer timeout_w;
    / / Create a socket connection
    Sd = socket(PF_INET, SOCK_STREAM, 0);
    If(sd < 0)
    {
        Printf("socket error\n");
        Return -1;
    }
    Bzero(&addr, sizeof(addr));
    Addr.sin_family = AF_INET;
    Addr.sin_port = htons(PORT);
    Addr.sin_addr.s_addr = INADDR_ANY;
    //normal bind
    If(bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0)
    {
        Printf("bind error\n");
        Return -1;
    }
    //Normal listen
    If(listen(sd, SOMAXCONN) < 0)
    {
        Printf("listen error\n");
        Return -1;
    }
    / / Set fd can be reused
    Int bReuseaddr=1;
    If(setsockopt(sd,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(bReuseaddr)) != 0)
    {
        Printf("setsockopt error in reuseaddr[%d]\n", sd);
        Return ;
    }
      
    / / Initialize io watcher, used to listen to fd
    Ev_io_init(&socket_accept, accept_cb, sd, EV_READ);
    Ev_io_start(loop, &socket_accept);
      
    / / Can send heartbeat packets to the far end
    //ev_timer_init(&timeout_w, timer_beat, 1., 0.);
    //ev_timer_start(loop, &timeout_w);
      
    Ev_run(loop, 0);
      
    Return 1;
}
  
Void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
    /*
        If there is a link, continue to listen to fd;
    */
    Struct sockaddr_in client_addr;
    Socklen_t client_len = sizeof(client_addr);
    Int client_sd;
    / / Create a client's io watcher
    Struct ev_io *w_client = (struct ev_io*) malloc(sizeof(struct ev_io));
      
    If(w_client == NULL)
    {
        Printf("malloc error in accept_cb\n");
        Return ;
    }
      
    If(EV_ERROR & revents)
    {
        Printf("error event in accept\n");
        Return ;
    }
      
    / / Get the fd connected to the client
    Client_sd = accept(watcher->fd, (struct sockaddr*)&client_addr, &client_len);
    If(client_sd < 0)
    {
        Printf("accept error\n");
        Return;
    }
    / / If the number of connections is outside the specified range, close the connection
    If( client_sd > MAX_ALLOWED_CLIENT)
    {
        Printf("fd too large[%d]\n", client_sd);
        Close(client_sd);
        Return ;
    }
      
    If(libevlist[client_sd] != NULL)
    {
        Printf("client_sd not NULL fd is [%d]\n", client_sd);
        Return ;
    }
      
    Printf("client connected\n");
    / / Monitor new fd
    Ev_io_init(w_client, read_cb, client_sd, EV_READ);
    Ev_io_start(loop, w_client);
      
    Libevlist[client_sd] = w_client;
  
}
  
Void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
    Char buffer[BUFFER_SIZE];
    Ssize_t read;
      
    If(EV_ERROR & revents)
    {
        Printf("error event in read\n");
        Return ;
    }
    //Normal recv
    Read = recv(watcher->fd, buffer, BUFFER_SIZE, 0);
    If(read < 0)
    {
        Printf("read error\n");
        Return;
    }
      
    If(read == 0)
    {
        Printf("client disconnected.\n");
        //ev_io_stop(loop, watcher);
        //free(watcher);
        / / If the client disconnects, release the response resource, and close the listener
        Freelibev(loop, watcher->fd);
        Return;
    }
    Else
    {
        //buffer[read] = '\0';
        Printf("receive message:%s\n", buffer);
    }
    / / Return to the client
    Send(watcher->fd, buffer, read, 0);
    Bzero(buffer, read);
}
  
Void timer_beat(struct ev_loop *loop, struct ev_timer *watcher, int revents)
{
    Float timeout = 2.0;
    //You can send a heartbeat packet here, or you can do nothing.
    Printf("send beat per[%f]\n",timeout);
    Fflush(stdout);
      
    If(EV_ERROR & revents)
    {
        Printf("error event in timer_beat\n");
        Return ;
    }
      
    Ev_timer_set(watcher, timeout,0.);
    Ev_timer_start(loop, watcher);
    Return;
}
  
Int freelibev(struct ev_loop *loop, int fd)
{
    /*if(fd > MAX_ALLOWED_CLIENT)
    {
        Printf("more than MAX_ALLOWED_CLIENT[%d]", fd);
        Return -1;
    }*/
    / / Clean up related resources
      
    If(libevlist[fd] == NULL)
    {
        Printf("the fd already freed[%d]\n", fd);
        Return -1;
    }
      
    Close(fd);
    Ev_io_stop(loop, libevlist[fd]);
    Free(libevlist[fd]);
    Libevlist[fd] = NULL;
    Return 1;
} makefile: 
 
 
 
 
 
 
CC=gcc
FLAGS=-I. -I/home/lengzijian/c/libev/libev-4.11 
LDFLAGS=-L/usr/lib -L/home/lengzijian/c/libev/libev-4.11/.libs -lev -Wall
 
OBJECTS=server.o
ALL_BIN=server
 
all:$(ALL_BIN) 
 
$(ALL_BIN):$(OBJECTS) 
	$(CC) $(FLAGS) $(LDFLAGS) -o $@ $^
 
 
%.o:%.c
	$(CC) -c $< $(FLAGS) $(FLAGS)
 
clean:
	rm -fr $(OBJECTS)
	rm -fr $(ALL_BIN)
 Note the header file path in the makefile, and the path to the dynamic link library
 
 When testing, you only need telnet ip 57789