LibEvent中文幫助文檔--第18章【LibEvent編程示例】



LibEvent中文幫助文檔--第18章【LibEvent編程示例】


   返回主目錄


Libevent


快速可移植非阻塞式網絡編程

 

 

修訂歷史

版本

日期

作者

備註

V1.0

2016-11-15

周勇

Libevent編程中文幫助文檔

 

文檔是2009-2012年由Nick-Mathewson基於Attribution-Noncommercial-Share Alike許可協議3.0創建,未來版本將會使用約束性更低的許可來創建.

此外,本文檔的源代碼示例也是基於BSD"3條款""修改"條款.詳情請參考BSD文件全部條款.本文檔最新下載地址:

英文:http://libevent.org/

中文:http://blog.csdn.net/zhouyongku/article/details/53431750

請下載並運行"gitclonegit://github.com/nmathewson/libevent- book.git"獲取本文檔描述的最新版本源碼.




<<上一章>>


18.1Event客戶端服務器示例

18.1.1客戶端

client.c

/*Author:ZhouYong
http://blog.csdn.net/zhouyongku
Date:2016-11-29*/

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<event2/event.h>

#define MAX_READ_MSG_LEN	4096

const 	char * 	g_szServerIP = "127.0.0.1";
const	short		g_nConnectPort = 15623;

//Wait For socket can read,then call the callback fun.
void OnClientRead(int fd,short narg,void *pParam );


int main()
{
	

	/*------------------------ConnectToServer------------------------*/
	int fd = socket(PF_INET,SOCK_STREAM,0);
	if( fd<0 )
	{
		printf("Client Create Socket Error!\n");
		return -1;
	}

	sockaddr_in addr;
	inet_aton(g_szServerIP,&addr.sin_addr);
	addr.sin_port = htons(g_nConnectPort);
	addr.sin_family = PF_INET;
	
	if( connect(fd,(sockaddr*)&addr,sizeof(addr)) <0 )
	{
		close(fd);
		printf("Client Connect To Server ip=%s port=%d failed!!\n",g_szServerIP,g_nConnectPort);
		return -1;
	}

	printf("Client Connect To Server ip=%s port=%d success!\n",g_szServerIP,g_nConnectPort);

	sleep(1);
	/*------------------------CreateEventBase------------------------*/
	event_base *pBase = event_base_new();
	if( NULL == pBase )
	{
		printf("Client Create Event Base Error!\n");
		return -1;
	}


	/*------------------------CreateEvent------------------------*/
	event	*pEvent = event_new(pBase,fd,EV_READ|EV_PERSIST,OnClientRead,NULL);
	if( NULL == pEvent )
	{
		printf("Client Create Event Failed!\n");
		return -1;
	}


	/*------------------------Add Event To List------------------------*/
	event_add(pEvent,NULL);




	/*------------------------EventLoop------------------------*/
	event_base_dispatch(pBase);
	
	return 0;

}

void OnClientRead(int fd,short narg,void *pParam )
{

	char szMsg[MAX_READ_MSG_LEN] = { 0 };
	int nLen = read(fd, szMsg, MAX_READ_MSG_LEN-1);
	if( nLen <= 0 )
	{
		printf("OnClientRead failed of read message!\n");
		return;
	}

	szMsg[nLen] = '\0';

	printf("OnClientRead read msg=%s\n", szMsg);

}

18.1.2服務器端

 

server.c

/*Author:ZhouYong
http://blog.csdn.net/zhouyongku
Date:2016-11-29*/
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<event2/event.h>

#define MAX_LISTEN_SOCKET_NUM	1024
#define MAX_SEND_MSG_LEN		4096
const	short		g_nConnectPort = 15623;

void OnAccept( int fdListener,short nArg,void *pParam );

int main()
{

	/*------------------------Bind socket and listen------------------------*/
	sockaddr_in addr;
	addr.sin_addr.s_addr= 0;
	addr.sin_family = PF_INET;
	addr.sin_port = htons(g_nConnectPort);

	int fdListener = socket(PF_INET,SOCK_STREAM,0);
	
	if( fdListener<0 )
	{
		printf("Server Create Socket Error!\n");
		return -1;
	}


	if( bind(fdListener,(sockaddr*)&addr,sizeof(addr)) <0 )
	{
		printf("Server bind Socket Error!\n");
		return -1;
	}

	if( listen(fdListener,MAX_LISTEN_SOCKET_NUM) <0 )
	{
		printf("Server listen  Error!\n");
		return -1;
	}

	
	/*------------------------Create eventbase------------------------*/
	event_base *pBase = event_base_new();
	if( NULL == pBase )
	{
		printf("Server Create Event Base Error!\n");
		return -1;
	}
	
	/*------------------------CreateEvent------------------------*/
	event	*pEvent = event_new(pBase,fdListener,EV_READ|EV_PERSIST,OnAccept,pBase);
	if( NULL == pEvent )
	{
		printf("Server Create Event Failed!\n");
		return -1;
	}

	

	/*------------------------Add Event To List------------------------*/
	event_add(pEvent,NULL);




	/*------------------------EventLoop------------------------*/
	event_base_dispatch(pBase);
	
	return 0;


}


void OnAccept( int fdListener,short nArg,void *pParam )
{
	if( NULL == pParam ) return;
	
	event_base *pBase = (event_base*)pParam;
	
	
	evutil_socket_t fdClient;
	struct sockaddr_in addrClient;
	socklen_t nAddrLen;

	fdClient = accept(fdListener, (sockaddr*)&addrClient, &nAddrLen );
	if( fdClient <0 )
	{
		printf("Server OnAccept failed of accept!");
		return;
	}
	
	evutil_make_socket_nonblocking(fdClient);

	printf("Server accept socket =%d!\n",fdClient);

	//event *pEvent = event_new(pBase,fdClient,EV_READ|EV_PERSIST,......


}

 

18.1.3編譯源碼

編譯

[root@localhost Test2]# g++ -c client.c 
[root@localhost Test2]# g++ -levent client.o -o client
[root@localhost Test2]# g++ -c server.c
[root@localhost Test2]# g++ -levent server.o -o server

 

18.1.4腳本文件

批量運行腳本

[root@localhost Test2]# vi run.sh
#!/bin/bash
for i in $(seq 1 100 )
do
    ./client &

done   

18.1.4運行測試

運行服務端

[root@localhost Test2]# rm -rf *.o
[root@localhost Test2]# ll
total 44
-rwxr-xr-x. 1 root root 13340 Nov 29 22:33 client
-rw-r--r--. 1 root root  2156 Nov 29 21:45 client.c
-rw-r--r--. 1 root root    61 Nov 29 22:19 run.sh
-rwxr-xr-x. 1 root root 13239 Nov 29 22:34 server
-rw-r--r--. 1 root root  2267 Nov 29 22:12 server.c
[root@localhost Test2]# ./server 


批量運行客戶端

[root@localhost Test2]# sh run.sh 
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!
Client Connect To Server ip=127.0.0.1 port=15623 success!

服務器反饋

[root@localhost Test2]# ./server 
Server accept socket =7!
Server accept socket =8!
Server accept socket =9!
Server accept socket =10!
Server accept socket =11!
Server accept socket =12!
Server accept socket =13!
Server accept socket =14!
Server accept socket =15!
Server accept socket =16!
Server accept socket =17!
Server accept socket =18!
Server accept socket =19!
Server accept socket =20!
Server accept socket =21!

性能觀察

[root@localhost Test2]# top
top - 22:41:26 up  1:59,  6 users,  load average: 0.04, 0.05, 0.13
Tasks: 424 total,   2 running, 422 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.2 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3874956 total,  2739080 free,   644724 used,   491152 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  2969920 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                           
 3001 root      20   0  252412   1492   1080 S   0.7  0.0   0:33.81 pcscd                                                                                                                                             
 1002 root      20   0  243868   6316   4808 S   0.3  0.2   0:09.48 vmtoolsd                                                                                                                                          
 3498 zhouyong  20   0 1168896  24696  16296 S   0.3  0.6   0:17.31 gnome-settings-                                                                                                                                   
 3748 zhouyong  20   0  144768   3360   2520 S   0.3  0.1   0:16.37 escd                                                                                                                                              
 6600 root      20   0  143828   6124   3884 S   0.3  0.2   0:22.44 sshd                                                                                                                                              
    1 root      20   0  192088   7388   2616 S   0.0  0.2   0:05.42 systemd                                                                                                                                           
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.04 kthreadd                                                                                                                                          
    3 root      20   0       0      0      0 S   0.0  0.0   0:00.19 ksoftirqd/0                                                                                                                                       
    5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H                                                                                                                                      
    6 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kworker/u128:0                                                                                                                                    
    7 root      rt   0       0      0      0 S   0.0  0.0   0:00.24 migration/0                                                                                                                                       
    8 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh                                                                                                                                            
    9 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcuob/0                                                                                                                                           
   10 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcuob/1 

18.2BufferEvent客戶端服務器示例

18.2.1客戶端

client.c

/*Author:ZhouYong
http://blog.csdn.net/zhouyongku
Date:2016-11-29
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<event2/event.h>
#include<event2/bufferevent.h>

#define MAX_READ_MSG_LEN	4096

const 	char * 		g_szServerIP = "127.0.0.1";
const	short		g_nConnectPort = 15623;
const	char *  	g_szWellcomeMsg="This is bufferevent test client demo.\n";
const	char*		g_szUserMsg="Hi,I'm client with bufferevent!\n";

//Wait For data in buffer is ready to read,then call the callback fun.
void OnRead(bufferevent *pBufEvent,void *pParam );

//Wait For  buffer can write now,then call the callback fun.
void OnWrite(bufferevent *pBufEvent,void *pParam );

//Wait while some event happen to the socket,then call the callback fun.
void OnEvent(bufferevent *pBufEvent,short nEventType,void *pParam );

int main()
{
	
	printf(g_szWellcomeMsg);
	
	/*----------Use Bufferevent to connect server--------------*/

	sockaddr_in addr;
	inet_aton(g_szServerIP,&addr.sin_addr);
	addr.sin_port = htons(g_nConnectPort);
	addr.sin_family = PF_INET;
	
	event_base *pBase = event_base_new();
	if( NULL == pBase )
	{
		printf("Client Create Event Base Error!\n");
		return -1;
	}

	bufferevent *pBufEvent;

	//recv an close message
	pBufEvent = bufferevent_socket_new(pBase,-1,BEV_OPT_CLOSE_ON_FREE);
	if( NULL == pBufEvent )
	{
		printf("Client bufferevent_socket_new Error!\n");
		return -1;
	}

	bufferevent_setcb(pBufEvent,OnRead,OnWrite,OnEvent,NULL);
	bufferevent_enable(pBufEvent, EV_READ | EV_WRITE | EV_PERSIST);
	
	if (bufferevent_socket_connect(pBufEvent,(sockaddr* )&addr,sizeof(addr)) < 0) 
	{
		printf("Client bufferevent_socket_connect Error!\n");
		bufferevent_free(pBufEvent);
		return -1;
	}

	printf("Server bufferevent_socket_connect ip=%s port=%d success!\n",g_szServerIP,g_nConnectPort);

	bufferevent_write(pBufEvent,g_szUserMsg,strlen(g_szUserMsg)+1);
	
	event_base_dispatch(pBase);
	
	return 0;

}

void OnRead(bufferevent *pBufEvent,void *pParam )
{
	printf("client OnRead!\n");
	char szMsg[MAX_READ_MSG_LEN] = { 0 };
	
	int nLen = bufferevent_read(pBufEvent,szMsg,MAX_READ_MSG_LEN );
	if( nLen >0 )
	{
		printf("Client OnRead Msg=[%s]\n",szMsg);
	}
}
void OnWrite(bufferevent *pBufEvent,void *pParam )
{
	printf("client OnWrite!\n");

}
void OnEvent(bufferevent *pBufEvent,short nEventType,void *pParam )
{

	if (nEventType & BEV_EVENT_EOF)
	{
		printf("OnEvent connection closed\n");
		bufferevent_free(pBufEvent);
	}
	else if ( nEventType &BEV_EVENT_CONNECTED )
	{
		printf("OnEvent connect to server success!\n");
	}
	else if (nEventType & BEV_EVENT_ERROR)
	{
		printf("OnEvent meet some other error\n");
	}
	else
	{
		//TODO:......
	}

}	

 

18.2.2服務器端

 

server.c

/*Author:ZhouYong
http://blog.csdn.net/zhouyongku
Date:2016-11-29
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<event2/event.h>
#include<event2/bufferevent.h>
#include<event2/util.h>
#include<event2/listener.h>

#define MAX_READ_MSG_LEN	4096
#define MAX_LISTEN_SOCKET_NUM	1024
const 	char * 		g_szServerIP = "127.0.0.1";
const	short		g_nConnectPort = 15623;
const	char *  	g_szWellcomeMsg="This is bufferevent test Server demo.\n";
const	char*		g_szUserMsg="Hi,I'm Server with bufferevent!\n";


//Wait for an socket connect in,then call the callback fun
void OnAccept(evconnlistener *listener, evutil_socket_t fdClient,
			sockaddr *pAddr, int nSocklen, void *pParam);		 

//Wait For data in buffer is ready to read,then call the callback fun.
void OnRead(bufferevent *pBufEvent,void *pParam );

//Wait For  buffer can write now,then call the callback fun.
void OnWrite(bufferevent *pBufEvent,void *pParam );

//Wait while some event happen to the socket,then call the callback fun.
void OnEvent(bufferevent *pBufEvent,short nEventType,void *pParam );


int main()
{
	
	printf(g_szWellcomeMsg);


	sockaddr_in addr;
	addr.sin_addr.s_addr = 0;
	addr.sin_port = htons(g_nConnectPort);
	addr.sin_family = PF_INET;
	
	event_base *pBase = event_base_new();
	if( NULL == pBase )
	{
		printf("Server Create Event Base Error!\n");
		return -1;
	}

	
	evconnlistener *pEvListener = evconnlistener_new_bind(pBase, 
					OnAccept, 
					pBase,
					LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,
					MAX_LISTEN_SOCKET_NUM, 
					(sockaddr*)&addr,
					sizeof(addr));
	if( NULL == pEvListener )
	{
		event_base_free(pBase);
		printf("Server evconnlistener_new_bind failed!\n");
		return -1;
	}
	event_base_dispatch(pBase);

	evconnlistener_free(pEvListener);

	event_base_free(pBase);

	return 0;

}

void OnAccept(evconnlistener *listener, evutil_socket_t fdClient,
			sockaddr *pAddr, int nSocklen, void *pParam)
{
	if( NULL == pParam || NULL == pAddr ) return ;

	/*const char *const strIP = inet_ntoa(pAddr->sa_data);
	
	if( NULL == strIP ) 
	{
		printf("Server OnAccept meet an error!\n");
		return ;
	}*/
	
	printf("Server OnAccept an socket ip=%s,id=%d\n", pAddr->sa_data,fdClient);

	event_base *pBase = (event_base*)pParam;

	//*-----------Allocate a bufferevent for client connection-----------*/	
	bufferevent *pBufEvent =  bufferevent_socket_new(pBase, 		
				fdClient,
				BEV_OPT_CLOSE_ON_FREE);
	if( NULL == pBufEvent )
	{
		printf("Server bufferevent_socket_new Error!\n");
		return;
	}
	bufferevent_setcb(pBufEvent, OnRead, OnWrite, OnEvent, NULL);
	bufferevent_enable(pBufEvent, EV_READ | EV_WRITE| EV_PERSIST);
	

}


void OnRead(bufferevent *pBufEvent,void *pParam )
{
	printf("Server  OnRead!\n");
	char szMsg[MAX_READ_MSG_LEN] = { 0 };
	
	int nLen = bufferevent_read(pBufEvent,szMsg,MAX_READ_MSG_LEN );
	if( nLen >0 )
	{
		printf("Server OnRead Msg=[%s]\n",szMsg);
	}
	bufferevent_write(pBufEvent,g_szUserMsg,strlen(g_szUserMsg)+1);
}
void OnWrite(bufferevent *pBufEvent,void *pParam )
{
	printf("Server OnWrite!\n");

}
void OnEvent(bufferevent *pBufEvent,short nEventType,void *pParam )
{

	if (nEventType & BEV_EVENT_EOF)
	{
		printf("OnEvent connection closed\n");
		//這將自動close套接字和free讀寫緩衝區
		bufferevent_free(pBufEvent);
	}
	else if ( nEventType &BEV_EVENT_CONNECTED )
	{
		printf("OnEvent connect to server success!\n");
	}
	else if (nEventType & BEV_EVENT_ERROR)
	{
		printf("OnEvent meet some other error\n");
	}
	else
	{
		//TODO:......
	}

}	

 

18.2.3編譯源碼

18.1.3

18.2.4腳本文件

18.1.4

18.2.4運行測試

運行服務端

[root@localhost Test3]# ./server 
This is bufferevent test Server demo.
Server OnAccept an socket ip=,id=7
Server  OnRead!
Server OnRead Msg=[Hi,I'm client with bufferevent!
]
Server OnWrite!

 

運行客戶端

[root@localhost Test3]# ./client 
This is bufferevent test client demo.
Server bufferevent_socket_connect ip=127.0.0.1 port=15623 success!
OnEvent connect to server success!
client OnWrite!
client OnRead!
Client OnRead Msg=[Hi,I'm Server with bufferevent!




發佈了81 篇原創文章 · 獲贊 118 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章