3.6 网络编程与reactor模式
2016-04-07 09:43
561 查看
postfix的网络编程内容可以分为三部分:
1inet_listen.c、unix_listen.c、fifo_listen.c实现服务器端,即实现基本的socket,listen,bind,accept,mkfifo等调用。
2inet_connect.c、unix_connect.c实现了客户端。
3inet_trigger.c、unix_trigger.c、fifo_trigger.c实现了“触发”式的客户端。
这里的“触发”指的是:不进行“会话”而仅仅是发送一次数据随即断开连接。
“触发”有两种方式:定时的和不定时的。qmgr和pickup模块需要被定时触发。定时触发在4.3.4中的master_wakeup_timer_event函数中实现(详情见4.3.4):
不定时的触发如cleanup模块向邮件队列(文件系统)写数据后,要触发qmgr模块,在/global/mail_stream.c的mail_stream_finish_file函数中,用vstream_fflush写数据后,调用mail_trigger触发qmgr模块。这类触发不需要定时事件,一旦cleanup模块完成写数据都会发生。
在smtp协议解析过程中,客户端与服务器端要进行你来我往的“交流”,而在cleanup模块将信件整理为record格式通知qmgr模块进行调度的场景中,cleanup模块仅需要“通知”一下qmgr模块,而不需要进行“会话”。所以smtpd.c使用了single_server.c做模板而qmgr.c使用了trigger_server.c做模板(见4.4)。
我们来看一下inet_trigger.c的inet_trigger函数
105 连接服务器,调用inet_connect.c中的inet_connect函数。
118-121 带超时的写。
126-128 安排一个时间事件,在此时间事件inet_trigger_event中执行close。即不进行“会话”,在一个限定时间内关闭连接。
仅靠基本的网络编程手段不足以应对网络编程的复杂性,我们还需要“模式”的支持,postfix采用了常见的Reactor模式:即结合多路复用函数和回调函数,当多路复用函数选定文件描述符后,执行相应的回调函数,实现“事件”编程。
1inet_listen.c、unix_listen.c、fifo_listen.c实现服务器端,即实现基本的socket,listen,bind,accept,mkfifo等调用。
2inet_connect.c、unix_connect.c实现了客户端。
3inet_trigger.c、unix_trigger.c、fifo_trigger.c实现了“触发”式的客户端。
这里的“触发”指的是:不进行“会话”而仅仅是发送一次数据随即断开连接。
“触发”有两种方式:定时的和不定时的。qmgr和pickup模块需要被定时触发。定时触发在4.3.4中的master_wakeup_timer_event函数中实现(详情见4.3.4):
/master/master_wakeup.c static char wakeup = TRIGGER_REQ_WAKEUP; switch (serv->type) { case MASTER_SERV_TYPE_INET: status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); break; case MASTER_SERV_TYPE_UNIX: status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); break; #ifdef MASTER_SERV_TYPE_PASS case MASTER_SERV_TYPE_PASS: status = pass_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); break;
不定时的触发如cleanup模块向邮件队列(文件系统)写数据后,要触发qmgr模块,在/global/mail_stream.c的mail_stream_finish_file函数中,用vstream_fflush写数据后,调用mail_trigger触发qmgr模块。这类触发不需要定时事件,一旦cleanup模块完成写数据都会发生。
在smtp协议解析过程中,客户端与服务器端要进行你来我往的“交流”,而在cleanup模块将信件整理为record格式通知qmgr模块进行调度的场景中,cleanup模块仅需要“通知”一下qmgr模块,而不需要进行“会话”。所以smtpd.c使用了single_server.c做模板而qmgr.c使用了trigger_server.c做模板(见4.4)。
我们来看一下inet_trigger.c的inet_trigger函数
/util/inet_trigger.c 91 /* inet_trigger - wakeup INET-domain server */ 92 93 int inet_trigger(const char *service, const char *buf, ssize_t len, int timeout) 94 { 95 const char *myname = "inet_trigger"; 96 struct inet_trigger *ip; 97 int fd; 98 99 if (msg_verbose > 1) 100 msg_info("%s: service %s", myname, service); 101 102 /* 103 * Connect... 104 */ 105 if ((fd = inet_connect(service, BLOCKING, timeout)) < 0) { 106 if (msg_verbose) 107 msg_warn("%s: connect to %s: %m", myname, service); 108 return (-1); 109 } 110 close_on_exec(fd, CLOSE_ON_EXEC); 111 ip = (struct inet_trigger *) mymalloc(sizeof(*ip)); 112 ip->fd = fd; 113 ip->service = mystrdup(service); 114 115 /* 116 * Write the request... 117 */ 118 if (write_buf(fd, buf, len, timeout) < 0 119 || write_buf(fd, "", 1, timeout) < 0) 120 if (msg_verbose) 121 msg_warn("%s: write to %s: %m", myname, service); 122 123 /* 124 * Wakeup when the peer disconnects, or when we lose patience. 125 */ 126 if (timeout > 0) 127 event_request_timer(inet_trigger_event, (void *) ip, timeout + 100); 128 event_enable_read(fd, inet_trigger_event, (void *) ip); 129 return (0); 130 }
105 连接服务器,调用inet_connect.c中的inet_connect函数。
118-121 带超时的写。
126-128 安排一个时间事件,在此时间事件inet_trigger_event中执行close。即不进行“会话”,在一个限定时间内关闭连接。
仅靠基本的网络编程手段不足以应对网络编程的复杂性,我们还需要“模式”的支持,postfix采用了常见的Reactor模式:即结合多路复用函数和回调函数,当多路复用函数选定文件描述符后,执行相应的回调函数,实现“事件”编程。
相关文章推荐
- 3.2.7 INET_PROTO_INFO结构体:记录网络协议
- 映射网络驱动盘开机不需输入密码
- 浅谈Tomcat、web程序结构与Http协议
- 解决HttpServletResponse输出中文乱码问题
- SSL与TLS 区别 以及介绍
- 3.1.3 网络编程
- 虚拟机主机网络通信
- 什么是HTTPS
- PRML-贝叶斯网络
- Linux C高级编程——网络编程之包裹函数
- IOS混合编程 - Http for IOS (二)
- http://www.cnblogs.com/hoojo/archive/2011/06/08/2075201.html
- 深度学习(四)卷积神经网络入门学习
- WebAPI前置知识:HTTP与RestfulAPI
- The method getDispatcherType() is undefined for the type HttpServletRequest 升级到tomcat8(转)
- HttpClient
- [Angular 2] Using Promise to Http
- 解决 error while loading shared libraries: libghttp.so.1: cannot open shared object file
- 博客专题计划:《在实践中深入理解常见网络协议》
- 博客专题计划:《在实践中深入理解常见网络协议》