浮いている砂の上に高いプラットフォームを構築しないでください
libeventコンポーネント
evutil
違いを実現するために異なるプラットフォームネットワークを抽象化するために使用される共通の機能
イベント和event_bask
libeventのコアは、さまざまなプラットフォーム固有のイベントベースの非ブロッキングIOバックエンド用の抽象APIを提供します。これにより、プログラムは、ソケットの準備ができたとき、読み取りまたは書き込みを行い、基本的なタイムアウト関数と検出OS信号を処理できます。
bufferevent
Liventのイベントベースのコアに、より便利なカプセル化を提供します。ソケットが読み取りおよび書き込みの準備ができていることをプログラムに通知するだけでなく、プログラムが
バッファリングされた読み取りおよび書き込み操作を要求できるようにし、IOが実際にいつ発生したかを知ることができます(buffereventインターフェイスには複数のバックエンドがあり、これは次の方法で変更できます)。システム。WindowsのIOCPなどの高速ノンブロッキングIOモード。)
evbuffer
バッファ機能はbufferevent層の下に実装され、便利で効果的なアクセス機能が提供されます。
evhttp
単純なHTTPクライアント/サーバー実装
evdns
単純なDNSクライアント/サーバーの実装
evrpc
単純なRPCの実装
libeventライブラリ
libevent_core
すべてのevent_base、evbuffer、bufferevent、およびユーティリティ関数を含む、すべてのコアイベントおよびバッファ関数
libevent_extra
HTTP、DNS、RPCなど、プログラムが必要とする場合と必要としない場合があるプロトコル固有の機能を定義します
ログモジュール分析
4つのレベルのログを提供します
#define EVENT_LOG_DEBUG 0
#define EVENT_LOG_MSG 1
#define EVENT_LOG_WARN 2
#define EVENT_LOG_ERR 3
ユーザーは、libevntからログメッセージを受信するためのコールバックを定義する必要があります。
typedef void (*event_log_cb)(int severity, const char *msg);
void event_set_log_callback(event_log_cb cb);
パラメータからわかるように、ユーザーは取得するログメッセージのレベルを指定し、ログを受信するためのバッファメッセージを指定できます。
同時に呼び出しevent_set_log_callback
、カスタム関数のコールバックをパラメータとして設定して、ログの取得を完了します。関数、対数定義されたユーザのコールバック関数を受信するために変数を使用libevent log_fnを見ることができます。ログ情報を受信したくない場合は、関数を再度呼び出して、パラメーターnullptrを指定します。event_set_log_callback
event_set_log_callback
static event_log_cb log_fn = NULL;
static void
event_log(int severity, const char *msg)
{
if (log_fn)
log_fn(severity, msg);//如果用户注册了回调,则将相应等级的日志消息传递给用户
else {
const char *severity_str;
switch (severity) {
case _EVENT_LOG_DEBUG:
severity_str = "debug";
break;
case _EVENT_LOG_MSG:
severity_str = "msg";
break;
case _EVENT_LOG_WARN:
severity_str = "warn";
break;
case _EVENT_LOG_ERR:
severity_str = "err";
break;
default:
severity_str = "???";
break;
}
(void)fprintf(stderr, "[%s] %s\n", severity_str, msg);//打印日志信息
}
}
例:
#include <event2/event.h>
static void GetLog(int severity, const char *msg)
{
const char *s;
switch (severity) {
case _EVENT_LOG_DEBUG: s = "debug"; break;
case _EVENT_LOG_MSG: s = "msg"; break;
case _EVENT_LOG_WARN: s = "warn"; break;
case _EVENT_LOG_ERR: s = "error"; break;
default: s = "?"; break; /* never reached */
}
//fprintf(logfile, "[%s] %s\n", s, msg);
std::cout << s << "====" << msg << std::endl;
}
event_set_log_callback(GetLog);//注册回调
定義済みのログコールバックでlibeventAPI関数を呼び出すことはできません。そうしないと、未定義の動作ログ関連の関数が発生する可能性があります。
#ifdef __GNUC__
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
#define EV_NORETURN __attribute__((noreturn))
#else
#define EV_CHECK_FMT(a,b)
#define EV_NORETURN
#endif//当编译器是GNU的时候才会进行格式匹配检测
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
void event_sock_err(int eval, evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(3,4) EV_NORETURN;
void event_sock_warn(evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(2,3);
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
format (archetype, string-index, first-to-check)
其中,“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
void _event_debugx(const char *fmt, ...) EV_CHECK_FMT(1,2);
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
上記は、ログの関連API関数です。その中で、EV_CHECK_FMT
は、フォーマットが一致するかどうかをチェックするマクロです。参照リンク:https: //blog.csdn.net/xiaozi0221/article/details/106893648
attribute format属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。format属性告诉编译器,按照printf, scanf等标准C函数参数格式规则对该函数的参数进行检查。这在我们自己封装调试信息的接口时非常的有用。
format (archetype, string-index, first-to-check)
其中,“archetype”指定是哪种风格;“string-index”指定传
入函数的第几个参数是格式化字符串;“first-to-check”指定从函
数的第几个参数开始按上述规则进行检查。
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
以此为例,传入的第一个参数是格式化字符串,从函数的第二个参数开始进行检查