第一部分 Socket编程
Socket编程主要的原理是,通过socket系统调用,监听http/https请求。
主要的api有socket, bind, listen, accept, recv.
1. socket(int domain, int type, int protocol)
通过系统调用建立通信端口,domain 指定协议类型,PF_INET/AF_INET Ipv4网络协议
type 数据流控制协议,如tcp
protocol 协议编号 如 IPPROTO_TCP
2.bind(int socket, struct sockaddr *addr, int addrlen)
将通信端口与地址和端口绑定,地址可以为某一个网卡地址,也可绑定到本机的所有网卡上INADDR_ANY(0.0.0.0)。
addrlen addr结构体的长度
3.listen(int socket , int backlog) 指定socket通信的模式。
只适用SOCK_STREAM或SOCK_SEQPACKET的socket类型。backlog最大连接数上限。
4.accept(int socket, struct sockaddr *clientaddr, int clientaddrlen)
等待接收客户端连接连接,返回一个新的socket。clientaddr 请求发起方的地址。
5.recv(int socket, void *buffer, int buffersize, unsigned int flags)
将客户端发送到socket中的数据读到buffer中。flags 指定读取数据时的处理方式。
6.int send(int s, const void *msg, int len, unsigned int flags)将数据由指定的socket 传给对方主机。参数s为已建立好连接的socket。
第二部分 I/O复用
通过accept 接收到client的请求后,读取请求的数据做相应的处理,此时其他的链接需要等待。为了提高响应效率,需要在收到client的请求后,把请求处理的工作交给其他进程去处理,主进程继续响应后续的请求。以kqueue模型进行说明。
1.kqueue() 创建一个队里
2.struct event 结构体
不同的描述符类型,相应的filter类型不同。
ident 描述符
filter 描述符上的事件
flags事件处理动作 add/delete
fflags 和描述符有关
3.ENV_SET 初始化事件的宏
4.kevent($k, struct event *changeEventList, nchangeEventList, struct event *firedEventList, nfiredEventList, struct timestemp *time)
第三部分 Socket与I/O复用结合
先创建一个socket,将socket放入kq,当有链接到达时,kevent会获得一个触发的事件,在这个事件中有socket的描述符,通过accept方法,用新的socket去接管这个请求,并把新socket也放入kq中,由在新socket处理用户请求的时候,主socket可以同时接收新请求。
TCP 监听 socket,如果在完成的连接队列 ( 已收三次握手最后一个 ACK) 中有数据,此事件将被通知。收到该通知的应用一般调用 accept(),且可通过 data 获得完成队列的节点个数。 流或数据报 socket,当协议栈的 socket 层接收缓冲区有数据时,该事件会被通知,并且 data 被设置成可读数据的字节数。