网站建设营销企业/竞价推广代运营公司
背景知识
Socket
套接字。 客户端和服务端通信时,客户端需要数据出口,服务端需要数据入口,这两个出入口就是Socket。数据接收方新建socket后需要绑定ip和端口号,这样客户端才能链接上socket。连接的过程就是 三次握手
FD file descriptor
文件描述符。linux中有 一切皆文件的说法。这个FD可以理解成文件的索引。Socket 同样也是一种资源,也会对应一个FD。
再来说一下数据读取和写入:
首先,socket的操作都是在内核空间去做的。
其次,服务器通过网卡接收数据,接收到的数据会放在内核空间, 也就是socket缓冲区,此时处理逻辑的程序是无法操作这部分数据,所以内核空间封装read和write函数 供用户空间使用。
最终,数据处理需要在用户空间操作。
IO模型
假设你是一个老师(服务端)正在收作业,学生(客户端)做完作业后即可收上来
- 同步阻塞:逐个收作业,先A再BCD,如果A还没做完,你会等待,指导A完成才能继续收B的作业。
- 同步非阻塞:逐个收作业,先A再BCD,如果A还没做完,你会跳过等待,继续收B的作业。
- select poll:你不去主动收作业,学生做完后会通知你,但是你不知道谁完成了,只是知道有人完成了,只能挨个问
- epoll:学生写完后,回告诉你谁写完了,你直接去收作业。
同步阻塞
sever1. 新建socket listen_fd = socket(domian,type,protocol)2. 绑定端口. bind(listen_fd,addr,addlen)3. 开启监听. listen(listen_fd)4. 执行while(true){// 建立连接accept_fd = accept(listen_fd,addr,addlen);// 接收数据read(accept_fd,buf,nbyte)// 处理logicHandle(buf);}client11. 新建socket fd = socket(domian,type,protocol)2. 建立连接。 connect(fd,serv_addr,addlen)3. 写数据。 write(fd,buf,nbyte)
client21. 新建socket fd = socket(domian,type,protocol)2. 建立连接。 connect(fd,serv_addr,addlen)3. 写数据。 write(fd,buf,nbyte)
服务端在和其中一个客户端建立连接、接收数据、处理逻辑阶段都是阻塞的,别的客户端连接不进来。
同步非阻塞
severwhile(true){// 设置为非阻塞setNonbblocking(fd)// 建立连接accept_fd = accept(listen_fd,addr,addlen);if(accept_fd > 0){fd_list.add(accept_fd)}
client11. 新建socket fd = socket(domian,type,protocol)2. 建立连接。 connect(fd,serv_addr,addlen)3. 写数据。 write(fd,buf,nbyte)
服务端在和其中一个客户端建立连接、接收数据、处理逻辑阶段都是非阻塞的。如果当个某个客户端没有就绪,就直接下一次遍历。