저는 Windows 시스템을 사용하고 있기 때문에 최근 Libevent를 배우고 있습니다. 안타깝게도 VS에서 참조할 수 있는 프로그램이 거의 없습니다. 여러 블로그 글을 참고한 후. 나는 간단한 Libevent Server 프로그램을 탐색하고 작성했습니다. 또한 온라인에서 간단한 클라이언트 프로그램을 찾아 코드를 성공적으로 테스트했습니다. 오늘 여기에 메모를 해보세요.
Libevent는 정말 유용한 기능이고, 앞으로는 Windows에서 Libevent의 멀티스레딩을 구현해보겠습니다. 오늘은 참고용으로 제가 만든 것을 포스팅하겠습니다. vs2015를 컴파일하고 전달했습니다.
기본적으로 단일 스레드입니다(필요한 경우 다중 스레드로 구성 가능). 각 스레드에는 struct event_base 구조에 해당하는 단 하나의 이벤트 베이스가 있습니다. 연결된 이벤트 관리자)는 일정에 따라 일련의 이벤트를 호스트하는 데 사용됩니다. 이는 물론 운영 체제의 프로세스 관리와 비교할 수 있으며 더 간단합니다. 이벤트가 발생하면 event_base는 적절한 시간(즉시 필요하지는 않음)에 이벤트에 바인딩된 함수를 호출합니다(사전 정의된 일부 매개 변수와 바인딩 시 지정된 매개 변수 전달). 함수가 실행된 후 다음으로 돌아갑니다. 다른 행사 일정.
//event_base 만들기
struct event_base *base = event_base_new();
assert(base != NULL);
event_base 내부에는 하나 또는 일부 이벤트가 발생할 때까지 epoll/kqueue와 같은 시스템 호출을 차단한 후 이러한 이벤트를 처리하는 루프가 있습니다. 물론 이러한 이벤트는 이 event_base에 바인딩되어야 합니다. 각 이벤트는 fd 또는 POSIX 세마포어를 수신할 수 있는 구조체 이벤트에 해당합니다(여기에서는 fd만 설명합니다. 다른 이벤트는 매뉴얼을 참조하세요). struct 이벤트는 event_new를 사용하여 생성 및 바인딩하고, event_add를 사용하여 활성화합니다.
//이벤트 생성 및 바인딩
struct event *listen_event;
//매개변수: event_base, 모니터링된 fd, 이벤트 유형 및 속성, 바운드 콜백 함수, 콜백 함수에 대한 매개변수
listen_event = event_new(base, Listener, EV_READ | EV_PERSIST, callback_func, ( void*)base);
//매개변수: 이벤트, 시간 초과 시간(struct timeval *type, NULL은 시간 초과 설정이 없음을 의미)
event_add(listen_event, NULL) ;
참고: libevent에서 지원하는 이벤트 및 속성에는 다음이 포함됩니다(비트 필드를 사용하여 구현되었으므로 |를 사용하여 결합)
(a) EV_TIMEOUT: timeout
(b) EV_READ: 네트워크 버퍼에 데이터가 있는 한 콜백 함수가 동작합니다
(c) EV_WRITE: 네트워크 버퍼에 삽입된 데이터가 쓰여지는 동안 콜백 함수가 동작합니다. 트리거
(d) EV_SIGNAL: POSIX 세마포어, 매뉴얼 참조
(e) EV_PERSIST: 이 속성을 지정하지 않으면 콜백 함수가 트리거된 후 이벤트가 삭제됩니다
(f) EV_ET: Edge - 에지 트리거, EPOLL_ET
를 참조한 다음 발생하는 이벤트 처리를 시작할 수 있도록 event_base 루프를 시작해야 합니다. 이벤트 베이스 디스패치가 루프에서 시작되고 주의가 필요한 이벤트가 더 이상 없거나 event_loopbreak() / event_loopexit() 함수가 발생할 때까지 루프가 계속됩니다.
//이벤트 루프 시작
event_base_dispatch(base);
다음으로 이벤트에 바인딩된 콜백 함수 callback_func에 집중합니다. 여기에 전달되는 것은 소켓입니다. fd, 이벤트 유형 및 속성 bit_field, event_new에 전달된 마지막 매개변수(위의 줄로 이동하여 검토하세요. event_base가 전달되었습니다. 실제로는 구조를 할당하고 관련 데이터를 모두 넣은 다음 event_new에 던지면 여기에서 얻을 수 있습니다.) 프로토타입은 다음과 같습니다.
typedef void(*event_callback_fn)(evutil_socket_t sockfd, short event_type, void *arg)
서버의 경우 위 프로세스는 아마도 다음과 같습니다. :
1. 리스너 = 소켓(), 바인드(), 청취(), 비차단 설정(FCntl 설정은 POSIX 시스템에서 사용할 수 있으며 Windows는 설정할 필요가 없습니다.
실제로 Libevent는 통합 패키지 evutil_make_socket_nonblocking)
2. event_base 생성
3. 이벤트를 생성하고, 소켓을 event_base에 호스팅하고, 모니터링할 이벤트 유형을 지정하고, 해당 콜백을 바인딩합니다. 함수(및 함수에 제공되어야 하는 매개변수)
。对于listener socket来说,只需要监听EV_READ | EV_PERSIST
4. 启用该事件
5. 进入事件循环
-------------- -
6. (异步)当有client发起请求的时候,调用该回调函数,进行处理。
/*接下来关注下绑定到event的回调函数callback_func:传递给它的是一个socket fd、一个event类型及属性bit_field、以及传递给event_new的最后一个参数(去上面几行回顾一下,把event_base给传进来了,实际上更多地是分配一个结构体,把相关的数据都撂进去,然后丢给event_new,在这里就能取得到了)。*/
服务器端代码:Server.cpp
1 #include 2 #include 3 #include 4 #include <string.h> 5 #include 6 #include<event2> 7 #include 8 #include 9 #include 10 #pragma comment (lib,"ws2_32.lib") 11 #include 12 #define LISTEN_PORT 9999 13 #define LIATEN_BACKLOG 32 14 using namespace std; 15 /********************************************************************************* 16 * 函数声明 17 **********************************************************************************/ 18 //accept回掉函数 19 void do_accept_cb(evutil_socket_t listener, short event, void *arg); 20 //read 回调函数 21 void read_cb(struct bufferevent *bev, void *arg); 22 //error回调函数 23 void error_cb(struct bufferevent *bev, short event, void *arg); 24 //write 回调函数 25 void write_cb(struct bufferevent *bev, void *arg); 26 /********************************************************************************* 27 * 函数体 28 **********************************************************************************/ 29 //accept回掉函数 30 void do_accept_cb(evutil_socket_t listener, short event, void *arg) 31 { 32 //传入的event_base指针 33 struct event_base *base = (struct event_base*)arg; 34 //socket描述符 35 evutil_socket_t fd; 36 //声明地址 37 struct sockaddr_in sin; 38 //地址长度声明 39 socklen_t slen = sizeof(sin); 40 //接收客户端 41 fd = accept(listener, (struct sockaddr *)&sin, &slen); 42 if (fd > str; 99 printf("输入数据!");100 scanf_s("%d", &str);101 bufferevent_write(bev, &str, sizeof(str));102 }103 104 int main()105 {106 int ret;107 evutil_socket_t listener;108 WSADATA Ws;109 //Init Windows Socket110 if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0)111 {112 return -1;113 }114 listener = socket(AF_INET, SOCK_STREAM, 0);115 assert(listener > 0);116 evutil_make_listen_socket_reuseable(listener);117 struct sockaddr_in sin;118 sin.sin_family = AF_INET;119 sin.sin_addr.s_addr = 0;120 sin.sin_port = htons(LISTEN_PORT);121 if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) <p></p> <p>客户端代码:Client.cpp</p> <p class="cnblogs_code"></p> <pre class="brush:php;toolbar:false"> 1 /******* 客户端程序 client.c ************/ 2 #define _WINSOCK_DEPRECATED_NO_WARNINGS 3 #define _CRT_SECURE_NO_WARNINGS 4 #include 5 #include 6 #include 7 #include <string.h> 8 #include 9 #include10 #include11 12 #pragma comment (lib,"ws2_32.lib")13 int main(int argc, char *argv[])14 {15 WSADATA Ws;16 //Init Windows Socket17 if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0)18 {19 return 0;20 }21 int sockfd;22 char buffer[1024];23 struct sockaddr_in server_addr;24 struct hostent *host;25 int portnumber, nbytes;26 27 if ((host = gethostbyname("127.0.0.1")) == NULL)28 {29 fprintf(stderr, "Gethostname error\n");30 exit(1);31 }32 33 if ((portnumber = atoi("9999"))h_addr);51 52 /* 客户程序发起连接请求 */53 if (connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1)54 {55 fprintf(stderr, "Connect Error:%s\a\n", strerror(errno));56 exit(1);57 }58 59 while (true)60 {61 char MESSAGE[] = "hello server..\n";62 //bufferevent_write(buf_ev,MESSAGE,strlen(MESSAGE)); 63 // 64 if (-1 == (::send(sockfd, MESSAGE, strlen(MESSAGE), 0)))65 {66 printf("the net has a error occured..");67 break;68 }69 70 if ((nbytes = recv(sockfd, buffer, 1024,0)) == -1)71 {72 fprintf(stderr, "read error:%s\n", strerror(errno));73 exit(1);74 }75 76 buffer[nbytes] = '\0';77 printf("I have received:%s\n", buffer);78 memset(buffer, 0, 1024);79 80 Sleep(2);81 82 }83 /* 结束通讯 */84 closesocket(sockfd);85 exit(0);86 87 return 0;88 }</string.h>
回复内容:
[db:回复内容]

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
