在上一篇文章中,我们已经模拟了两个tcp客户端(telnet、tcp客户端)对tcp服务端发起请求的场景。得到了如下结果:
- tcp服务端只能一个接着一个地,以串行的方式执行各个请求
- tcp服务端处于阻塞状态时,有新的tcp请求到来,此时操作系统内核已经做好"三次握手",并在内核开辟临时缓存区,存放客户端发送过来的数据
1、问题思考
在请求量少的情况下,这种一个接着一个地执行方式,或许可以被接收。但量大的情况下,就比较慢了。这涉及到公司的声誉、盈利等等。这迫使我们要去解决,但又怎么解决?
2、生活场景启示
2.1、设想快递没有送货上门的情况
你有一个快递,但没有快递员送货上门。这时该怎么办?
答: 这时能做的,就是不定时地去快递点询问该快递单的情况。如下图所示
2.2、设想快递有送货上门的情况
这时能做的,就是保持联系方式正确无误。如下图所示
2.3、方式对比
效率上,显然是送货上门的情况高
3、生活场景的实现
3.1、socket连接在内核的体现关系
之前的文章中,有使用过socket_getsockname、socket_getpeername方法来获取此socket连接的本地和远程的信息(ip:port).从这个我们可以推断出,一条具体socket连接在内核关系如下图所示:
3.2、不定时"查询快递"的场景
由上面已经可以知道,多个请求到来时,其实内核已经与它们建立好连接,只是应用层的代码还没拿到socket连接(快递单)。那如果我们拿着这些建立好的socket连接(快递单),去内核(快递店)查询是否到来。这种方式可以解决掉串行执行的方式。
3.3、快递送货上门的场景
这种场景,相当于是你把联系方式绑定在快递单上,当快递到时,通知你拿。这对比到socket实现上,就相当于你在此socket连接上,绑定了一个回调函数。当这socket连接有任何状态改变,由内核进行触发回调函数