Bufferevent
Bufferevents are higher level than evbuffers: each has an underlying evbuffer for reading and one for writing, and callbacks that are invoked under certain circumstances.
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <event.h>
#include <event2/listener.h>
#define SVR_IP "127.0.0.1"
#define SVR_PORT 10000
#define BUFF_SIZE 1024
static void read_cb(struct bufferevent *bev, void *ctx) {
char buff[BUFF_SIZE];
int len;
memset(buff, 0, sizeof(buff));
/* Read data */
len = bufferevent_read(bev, buff, sizeof(buff));
printf("read: len=[%d] data=[%s]\n", len, buff);
/* Write data */
bufferevent_write(bev, buff, len);
}
static void write_cb(struct bufferevent *bev, void *ctx) {
printf("write finished\n");
}
static void event_cb(struct bufferevent *bev, short events, void *ctx) {
if (events & BEV_EVENT_EOF) {
printf("client disconnect\n");
bufferevent_free(bev);
} else if (events & BEV_EVENT_TIMEOUT) {
printf("client timeout\n");
bufferevent_free(bev);
} else {
/* Other case, maybe error occur */
bufferevent_free(bev);
}
}
static void accept_cb(struct evconnlistener *lev, evutil_socket_t fd,
struct sockaddr *sa, int socklen, void *ctx) {
struct event_base *evbase = ctx;
struct bufferevent *bev;
struct timeval tv;
printf("client connect from [%s:%u] over fd [%d]\n",
inet_ntoa(((struct sockaddr_in *) sa)->sin_addr),
(unsigned short) ntohs(((struct sockaddr_in *) sa)->sin_port), fd);
/* Create socket-based buffer event */
bev = bufferevent_socket_new(evbase, fd, BEV_OPT_CLOSE_ON_FREE);
if (bev == NULL) {
printf("bufferevent_socket_new() failed\n");
evutil_closesocket(fd);
return;
}
/* Set up callback function */
bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);
/* Set up timeout for data read */
tv.tv_sec = 5;
tv.tv_usec = 0;
bufferevent_set_timeouts(bev, &tv, NULL);
/* Enable read event */
bufferevent_enable(bev, EV_READ);
}
int main(void) {
struct event_base *evbase;
struct sockaddr_in sin;
struct evconnlistener *lev;
/* Initialize event base */
if ((evbase = event_base_new()) == NULL) {
printf("event_base_new() failed\n");
return -1;
}
/* Set up server address */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(SVR_IP);
sin.sin_port = htons(SVR_PORT);
/* Bind socket */
lev = evconnlistener_new_bind(evbase, accept_cb, evbase,
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr *) &sin, sizeof(sin));
if (lev == NULL) {
printf("bind() failed\n");
return -1;
} else {
printf("bind to [%s:%u] successfully\n", SVR_IP, SVR_PORT);
}
/* Enter event loop */
event_base_dispatch(evbase);
return 0;
}
編譯 (指定library path)
gcc -g -Wall -o server server.c -levent -I/opt/libevent-2.0.10-stable/include/ -L/opt/libevent-2.0.10-stable/lib/
Libevent 2.0 supports multiple threads.
回覆刪除How would you change your code to support multiple threads? Greetings.
As I know, if you want to read/write socket cross thread, you should perform some init. funciton:
刪除evthread_use_pthreads(),
evthread_make_base_notifiable()
and create object with thread safe flag:
BEV_OPT_THREADSAFE,
LEV_OPT_THREADSAFE
A7327EF8DD
回覆刪除bayan takipçi instagram
Danone Sürpriz Kodları
Ets 2 Para Hilesi
Clash Royale Taş Hilesi
Car Parking Coin Hilesi
Standoff 2 Gold Hilesi
Pubg Mobile Adam Görme Hilesi
First Blood Altın Hilesi
swivel accent chair set of 2 on sale
7266491C
回覆刪除Urfa
Osmaniye
Bingöl
Çanakkale
Adıyaman
Mardin
Yalova
Kütahya
Elazığ
46D8219A
回覆刪除Afyon
Niğde
Urfa
Kilis
Antep
Çankırı
Balıkesir
Osmaniye
Erzincan
E5B853EC
回覆刪除Silivri
Kahramankazan
Konyaaltı
Sarıçam
Elmadağ
Yüksekova
Kızılay
Midyat
Bayraklı
143D1D91
回覆刪除Adalar
Akhisar
Gölhisar
Avanos
Ürgüp
Bozüyük
Seyhan
Finike
Fındıklı