最近在学习libevent,顺便写了几个例子。按照Unix网络编程里的经典例子,从echo server开始。所谓echo server(回显服务器), 就是服务器将客户端发送过来的信息原封不动的发送回给客户端。
以下是结合libevent的初级回显服务器代码:
以下是结合libevent的初级回显服务器代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <event2/event.h>
#define MAX_BUF_SIZE 1024
int n_send(int fd, void *data, int len, int flag)
{
int nsent = 0;
int nleft = len;
void *ptr = data;
while (nleft > 0)
{
if ((nsent = send(fd, ptr, nleft, flag)) <= 0)
{
if (errno == EINTR)
{
continue;
}
else if (errno == EAGAIN)
{
usleep(100);
continue;
}
else
{
fprintf(stderr, "send() error: errno %d --- %s\r\n",
errno, strerror(errno));
break;
}
nleft -= nsent;
ptr += nsent;
}
return (len - nleft);
}
void do_read_cb(int fd, short events, void *arg)
{
char buf[MAX_BUF_SIZE];
struct event *ev = (struct event *)arg;
int len = 0;
again:
len = recv(fd, buf, sizeof(buf) - 1, 0);
if (len < 0)
{
if (errno == EINTR)
{
goto again;
}
fprintf(stderr, "some error happened while receiving data, errno: %d--- %s\r\n",
errno, strerror(errno));
event_free(ev);
close(fd);
return;
}
else if (len == 0)
{
fprintf(stderr, "socket closed by peer, fd = %d...\r\n", fd);
event_free(ev);
close(fd);
return;
}
n_send(fd, buf, len, 0);
}
void do_accept_cb(int fd, short events, void *arg)
{
evutil_socket_t sock;
struct sockaddr_in client;
socklen_t len = sizeof(client);
sock = accept(fd, (struct sockaddr *)&client, &len);
if (sock < 0)
{
fprintf(stderr, "accept() error: errno %d --- %s\r\n",
errno, strerror(errno));