C++ 网络编程
一、Reactor 网络编程模型
reactor
是一个事件处理模型。网络处理:因为用户层并不知道 IO
什么时候就绪 ,所以将对 IO
的处理转化为对事件的处理 。 网络模型构成: 非阻塞 IO
:操作 IO
,如果 IO
未就绪,IO
函数会立刻返回 。 IO
多路复用:检测多路 IO
是否就绪 。 工作流程: 注册事件: accept
:listenfd
注册读事件 ,如果读事件被触发了,说明 IO
就绪了,有新的客户端跟我们建立连接,那么处理事件的时候就可以直接调用 accept()
。connect
:服务器作为客户端去连接 MySQL
,connectfd
注册写事件 ,如果写事件被触发了,说明连接建立成功了。read
:clientfd
注册读事件 ,如果读事件被触发了,说明读缓冲区中有数据了(客户端发送数据了),我们再调用 read()
去读缓冲区中读数据。accept
返回 clientfd
。write
:clientfd
注册写事件 ,如果写事件被触发了,说明写缓冲区中有空间可以写数据,我们再调用 write()
往写缓冲区中写数据。被动断开连接:clientfd
注册读 / 写事件 ,read = 0
可以判断连接已经断开了,write = -1 && errno = EPIPE
也可以判断连接已经断开了。 处理事件:事件触发后,说明 IO
就绪了,处理相对应的 IO
。 封装流程: 事件对象:http_conn
连接、listenfd
、不同事件的回调函数。 事件控制接口:注册事件接口、注销事件接口。 事件循环:不断检测并发就绪的事件。
二、Reactor 和 Proactor 的区别
本质区别:IO
操作不同,reactor
中先检测 IO
是否就绪,然后再操作 IO
;proactor 只需要投递请求,所有 IO
操作由内核完成 。reactor
是同步 IO
网络模型 。 具体 IO
操作通过非阻塞 IO
来完成。 具体 IO
是否就绪,由 IO
多路复用来完成。 proactor
是异步 IO
网络模型 。 同步 IO
和 异步 IO
的区别: 同步 IO
:IO
函数调用后,立刻能获知 IO
操作的结果 。 异步 IO
:异步 IO
函数调用后,不能获知 IO
操作的结果,此时 IO
操作都由内核完成 。 阻塞 IO
和 非阻塞 IO
的区别: 当 IO
未就绪时,IO
函数是否立刻返回:立刻返回是非阻塞 IO
;阻塞等待是阻塞 IO
。 由 IO
函数的第一个参数,也就是具体的 fd
来决定,默认情况下,fd
是阻塞的,可修改为非阻塞。 IOCP
: CreateIoCompletionPort
:创建一个完成端口。创建 socket
、bind
、listen
,将该 socket
绑定到完成端口上。 根据 CPU
核心数创建工作线程,将完成端口传递到工作线程。 工作线程调用 GetQueuedCompletionStatus
等待 IO
完成。 处理业务逻辑(界定数据包)。 投递 IO
请求 AcceptEx
、RecvEx
、SendEx
到完成端口上。
三、连接断开有几种判定方式
服务器主动断开:主动调用 close()
。 服务器被动断开: 客户端主动调用 close()
:关闭读端和写端。shutdown()
:关闭读端或写端,或都关闭。 客户端直接退出。 IO
网络模型: read = 0
:读端关闭。(recv
第四个参数为 0
的时候和 read
等价)write = -1 && errno = EPIPE
:写端关闭。
IO
多路复用模型: EPOLLRDHUP
:读端关闭。EPOLLHUP
:读写端都关闭。 reactor
网络模型: 非阻塞 IO
可以用 IO
网络模型来判断连接是否断开。 也可以通过 IO
多路复用模型来判断连接是否断开。 proactor
网络模型:
四、接收客户端连接有几种方式
前提:服务端已经创建了 socket
,且该 socket
绑定在某个地址上(bind
),且该 socket
已经监听(listen
)。 阻塞的 IO
网络模型: 获知连接的唯一文件描述符。 获知连接的 IP
地址。 以阻塞线程的方式实现接收连接。 int clientfd = accept ( socket, & addr, sizeof ( addr) ) ;
非阻塞的 IO
网络模型: 如果接收到,就跟阻塞的 IO
表现一样。 如果没有接收到,clientfd = -1
,errno
为 EWOULDBLOCK
。 尝试一次接收连接。 int clientfd = accept ( socket, & addr, sizeof ( addr) ) ;
reactor
网络模型: 需要把 listenfd
注册它的读事件。 如果在事件循环中检测到 listenfd
的读事件,说明连接建立的 IO
已经就绪。 此时调用非阻塞 IO
accept
函数,将得到连接的 clientfd
和 IP
地址。 把接收连接抽象成一个事件。 proactor
网络模型: 投递 accept
请求:调用 AcceptEx
函数,传递一个重叠结构。 在工作线程中调用 GetQueueCompletionStatus
获取 IO
完成的结果。 如果有 IO
完成的事件,通过上面的函数可以获取重叠结构,从而知道具体是什么请求。 proactor
是异步 IO
处理ÿ
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/14647.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!