CppMore
Dive deep into the C++ core, and discover more!
CppMore

开始之前,再来看看流程图。 程序阻塞的主要有两部分,一个是等待数据到来,一个是将数据从内核复制到程序缓冲区。 事件选择模型,其实是在 select 模型的基础上更进一步地做了优化,这次优化把等待数据到来的这部分变成了非阻塞。而这主要是使用 WSAEventSelect 函数完成的,其原型如下: int WSAEventSelect ( SOCKET s, // 套接字 WSAEVENT hEventObject, // 事件对象 long lNetworkEvents // 网络事件 ); 事件选择给每个套接字绑定了一个事件,当发生指定网络事件的时候它会把绑定的事件变为 signaled 状态。 WSAEVENT 其实和之前在 Windows 线程同步中所说的内核对象事件是一样的,只是在这个函数中需要手动重置事件,为了清晰方便,所以弄了个 typedef,并提供了一个 WSACreateEvent 函数来创建手动重置的事件。 WSAEVENT event = WSACreateEvent(); 其实,这个 WSACreateEvent 函数就相当于调用以下语句: CreateEvent(NULL, TRUE, FALSE, NULL); lNetworkEvents 可以指定一些指定的网络事件,我们感兴趣的值如下: FD_READ FD_WRITE FD_ACCEPT FD_CONNECT… Continue Reading 网络模型之Event select

之前我们写了一些简单的网络程序,使用的都是基本的socket,这些程序有一个特点就是都是阻塞执行的。何谓阻塞呢?就是函数不会立即返回,直到等到结果才返回,像 accept,recv 就属于阻塞函数。 这种方式在人数(客户端)较少的情境下没有什么问题,但要是人数比较多了服务器就不能及时处理后面的客户请求了。若第一个连接的用户受理时间为 1 秒,那么第一百个连接的用户就得等 100秒。一个方法是可以为每个连接进来的用户开启一个线程进行处理,但开启太多的线程得付出很大的代价,所以这种方式也仅适用于用户较少的情况。 基于此,Windows 提供了一些网络模型来提高服务器同时接受客户端的能力。这里将会以几篇来分别讲解几个常用的模型: select 事件选择 重叠 IO IOCP 完成端口 这些模型从弱到强,从易到难。select 用来解决基本 socket 多线程的问题,适合 60 多个用户。事件选择异步了接受操作,适合 300-500 个用户。重叠 IO 就完全非阻塞了,适合上千个用户。IOCP 更加强大,可以支持万级别的用户,QQ 那些就使用的这个。 还有 Linux 上的 epoll 模型,这个和 IOCP 是一个级别的,因为我没怎么接触 Linux,所以这里就主要说 Windows 上的。 这里首先来说最简单的 select 模型,在此之前,我先画了一张图: 从图中可以看出有两个部分是阻塞的,一个是等待数据到来,一个是将数据从内核复制到程序缓冲区。 基本的 socket 这两个部分都是阻塞的,若是使用多线程的方式来处理,我们得用 n+1 个线程来服务 n 个客户。而申请大量线程代价极大且效率非佳,select 的目的就是来解决基本 socket… Continue Reading 网络模型之select

花开花落,倏忽一载便逝矣,新的一年,祝大家天天开心 HTTP即超文本传输协议(Hypertext Transfer Protocol),是Web通信所使用的协议。它是基于TCP/IP实现的协议,所以本篇需要先了解TCP通信,我们将使用TCP来写一个简单的Web服务器端,它可以响应浏览器的访问。 通信需要服务端和客户端,在这里浏览器就属于客户端,当访问一个网页时,浏览器内部会创建套接字和服务器进行通信。服务器会响应请求返回一些HTML格式的数据给浏览器,浏览器来把这些HTML数据解析成我们看到的漂亮的页面。 当我们在浏览器的地址栏上敲下一个域名地址后,浏览器会先通过默认DNS服务器获取该域名对应的IP地址,然后向服务器发送请求,请求有一定的标准,分为: 请求行 消息头 空行 消息体 现在来随便访问一个网址,这里使用的是 Firefox 浏览器,按 Ctrl+Shift+E 可以查看网络请求。 左边对应的是浏览器对服务器发出的请求,右边对应的是该条请求相关的信息。 我们先看左边的第一条,这里的请求方式是GET,表示想从服务器获取文件,获取的文件目录是/。然后服务器响应请求,发回了状态码302,表示Found重定向,我们本来访问的是 www.bing.com,现在被重定向到了 https://cn.bing.com/。这个重定向地址是通过响应头的location指定的,可以在右边看到。 https是加了SSL/TLS的协议,在需要安全的环境下,比如发送银行卡,身份信息等地方都会使用。只使用http这些信息很容易被窃听,SSL/TLS会对请求和响应的信息进行加密解密操作,保证数据安全。 接着同样是一些GET请求用于从服务器获取数据,状态码200 OK表示请求已经成功。还有常见的404 Not Found,表示找不到客户端请求的资源,这种情况我们就把链接转移到404错误页。现在来把对应的请求整理如下: 请求行: GET / HTTP/2.0 消息头: Accept:text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8 Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Connection:keep-alive Cookie:_EDGE_V=1; MUID=3802FC7ABA5D6F…ndefined; _UR=OMD=13190641321 Host:cn.bing.com Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/64.0 空行: 消息体: 请求行为一行数据,其中包含着请求方式,请求文件,HTTP版本。… Continue Reading HTTP协议之编写简单的Web服务器