简介
函数evconnlistener_new_bind
struct evconnlistener *
evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
void *ptr, unsigned flags, int backlog, const struct sockaddr *sa,
int socklen)
参数解析:
/**
Allocate a new evconnlistener object to listen for incoming TCP connections
on a given address.
@param base The event base to associate the listener with.
@param cb A callback to be invoked when a new connection arrives. If the
callback is NULL, the listener will be treated as disabled until the
callback is set.
@param ptr A user-supplied pointer to give to the callback.
@param flags Any number of LEV_OPT_* flags
@param backlog Passed to the listen() call to determine the length of the
acceptable connection backlog. Set to -1 for a reasonable default.
@param addr The address to listen for connections on.
@param socklen The length of the address.
*/
struct evconnlistener *
evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
void *ptr, unsigned flags, int backlog, const struct sockaddr *sa,
int socklen)
{
struct evconnlistener *listener;
evutil_socket_t fd;
int on = 1;
int family = sa ? sa->sa_family : AF_UNSPEC;
int socktype = SOCK_STREAM | EVUTIL_SOCK_NONBLOCK;
if (backlog == 0)
return NULL;
if (flags & LEV_OPT_CLOSE_ON_EXEC)
socktype |= EVUTIL_SOCK_CLOEXEC;
fd = evutil_socket_(family, socktype, 0);
if (fd == -1)
return NULL;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))<0)
goto err;
if (flags & LEV_OPT_REUSEABLE) {
if (evutil_make_listen_socket_reuseable(fd) < 0)
goto err;
}
if (flags & LEV_OPT_REUSEABLE_PORT) {
if (evutil_make_listen_socket_reuseable_port(fd) < 0)
goto err;
}
if (flags & LEV_OPT_DEFERRED_ACCEPT) {
if (evutil_make_tcp_listen_socket_deferred(fd) < 0)
goto err;
}
if (flags & LEV_OPT_BIND_IPV6ONLY) {
if (evutil_make_listen_socket_ipv6only(fd) < 0)
goto err;
}
if (sa) {
if (bind(fd, sa, socklen)<0)
goto err;
}
listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd);
if (!listener)
goto err;
return listener;
err:
evutil_closesocket(fd);
return NULL;
}
实例:监听服务器
#include <sys/types.h>
#include <event2/event-config.h>
#include <event2/listener.h>
#include <stdio.h>
#include <event.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%d $$ " format "\n" \
,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
/*
*/
void server_evconnlistener_cb(struct evconnlistener *listener, evutil_socket_t new_client, struct sockaddr *addr, int socklen, void *arg)
{
struct sockaddr_in *paddr = (struct sockaddr_in *)addr;
DEBUG_INFO("a new client fd = %d",new_client);
//char *inet_ntoa(struct in_addr in);
DEBUG_INFO("ip = %s,port = %d",inet_ntoa(paddr->sin_addr),ntohs(paddr->sin_port));
}
int main(int argc, char **argv){
struct event_base *base;
struct evconnlistener *listener;
struct sockaddr_in addr;
base = event_base_new();
if(base == NULL){
DEBUG_INFO("Couldn't create event_base");
exit(-1);
}
addr.sin_family = AF_INET;
// addr.sin_addr.s_addr = INADDR_ANY;
// addr.sin_addr.s_addr = inet_addr("0.0.0.0");
// addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_addr.s_addr = inet_addr("192.168.0.11");
addr.sin_port = htons(6666);
listener = evconnlistener_new_bind(
base,
server_evconnlistener_cb,
NULL,//传给cb的参数,本例中就是server_evconnlistener_cb
LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
5,//listen的第二个参数
(struct sockaddr*)&addr,//bind的第二个参数
sizeof(addr) //bind的第三个参数
);
if(listener == NULL){
DEBUG_INFO("evconnlistener_new_bind error");
exit(-1);
}
//开始监听集合中的事件
event_base_dispatch(base);
evconnlistener_free(listener);
event_base_free(base);
DEBUG_INFO("bye bye");
return 0;
}
测试:
运行程序,使用网络调试助手连接服务器的6666端口
程序输出信息:
实验分析: