转 http://taohui.org.cn/tcpperf1.html  陶辉 taohui.org.cn

回到应用层,往往只需要调用类似于accept的API就可以建立TCP连接。建立连接的流程大家都了解--三次握手,它如何与accept交互呢?下面以一个不太精确却通俗易懂的图来说明之:

研究过backlog含义的朋友都很容易理解上图。这两个队列是内核实现的,当服务器绑定、监听了某个端口后,这个端口的SYN队列和ACCEPT队列就建立好了。客户端使用connect向服务器发起TCP连接,当图中1.1步骤客户端的SYN包到达了服务器后,内核会把这一信息放到SYN队列(即未完成握手队列)中,同时回一个SYN+ACK包给客户端。一段时间后,在较中2.1步骤中客户端再次发来了针对服务器SYN包的ACK网络分组时,内核会把连接从SYN队列中取出,再把这个连接放到ACCEPT队列(即已完成握手队列)中。而服务器在第3步调用accept时,其实就是直接从ACCEPT队列中取出已经建立成功的连接套接字而已。

现有我们可以来讨论应用层组件:为何有的应用服务器进程中,会单独使用1个线程,只调用accept方法来建立连接,例如tomcat;有的应用服务器进程中,却用1个线程做所有的事,包括accept获取新连接。

原因在于:首先,SYN队列和ACCEPT队列都不是无限长度的,它们的长度限制与调用listen监听某个地址端口时传递的backlog参数有关。既然队列长度是一个值,那么,队列会满吗?当然会,如果上图中第1步执行的速度大于第2步执行的速度,SYN队列就会不断增大直到队列满;如果第2步执行的速度远大于第3步执行的速度,ACCEPT队列同样会达到上限。第1、2步不是应用程序可控的,但第3步却是应用程序的行为,假设进程中调用accept获取新连接的代码段长期得不到执行,例如获取不到锁、IO阻塞等。

那么,这两个队列满了后,新的请求到达了又将发生什么?

若SYN队列满,则会直接丢弃请求,即新的SYN网络分组会被丢弃;如果ACCEPT队列满,则不会导致放弃连接,也不会把连接从SYN列队中移出,这会加剧SYN队列的增长alt。所以,对应用服务器来说,如果ACCEPT队列中有已经建立好的TCP连接,却没有及时的把它取出来,这样,一旦导致两个队列满了后,就会使客户端不能再建立新连接,引发严重问题。

所以,如TOMCAT等服务器会使用独立的线程,只做accept获取连接这一件事,以防止不能及时的去accept获取连接。

那么,为什么如Nginx等一些服务器,在一个线程内做accept的同时,还会做其他IO等操作呢?

这里就带出阻塞和非阻塞的概念。应用程序可以把listen时设置的套接字设为非阻塞模式(默认为阻塞模式),这两种模式会导致accept方法有不同的行为。对阻塞套接字,accept行为如下图:

这幅图中可以看到,阻塞套接字上使用accept,第一个阶段是等待ACCEPT队列不为空的阶段,它耗时不定,由客户端是否向自己发起了TCP请求而定,可能会耗时很长。 对非阻塞套接字,accept会有两种返回,如下图:

由 http://www.cnblogs.com/diegodu/p/3977739.html 可知,无论是阻塞还是非阻塞都是同步的,因为都要阻塞在从内核考到应用程序的过程上。

非阻塞套接字上的accept,不存在等待ACCEPT队列不为空的阶段,它要么返回成功并拿到建立好的连接,要么返回失败。

所以,企业级的服务器进程中,若某一线程既使用accept获取新连接,又继续在这个连接上读、写字符流,那么,这个连接对应的套接字通常要设为非阻塞。原因如上图,调用accept时不会长期占用所属线程的CPU时间片,使得线程能够及时的做其他工作。

最新文章

  1. [PHP源码阅读]trim、rtrim、ltrim函数
  2. POJ 1163 The Triangle(简单动态规划)
  3. 使用React制作一个可配置的页面生成器[0]
  4. centos 关闭防火墙
  5. LoRaWAN移植笔记(一)__RTC闹钟链表的实现
  6. Android 调节当前Activity的屏幕亮度
  7. c# Oracle 远程连接方式 plsql 连接oracle 11g 64位
  8. BZOJ 1211 树的计数
  9. windows desktop.ini
  10. C# 窗体在线2,8,16进制转换以及,在线更新时间
  11. 游戏2048源代码 - C语言控制台界面版
  12. PHP冒泡排序、选择排序、插入排序
  13. Awesome CLI
  14. Excel文件上传功能实现
  15. 封装cuda/cudnn写卷积网络前向计算程序
  16. JS简单实现滚动自动加载新内容(懒加载)
  17. windows 允许其他电脑访问本地mysql数据库
  18. Iowait的成因、对系统影响及对策--systemtap
  19. A SimpleDataStore
  20. 关于Vue的一些小技巧

热门文章

  1. 9 款赏心悦目的 HTML5/CSS3 特效
  2. [zz] Install VSFTP
  3. 济南学习 Day 2 T3 am
  4. Codevs 1014 装箱问题
  5. SNRO:Number Range
  6. ProgressIndicator显示进度条以及一些文字信息
  7. jquery的change 事件
  8. Sql 执行删除修改之前添加备份
  9. Gulpfile.js——编译、压缩、合并js和css文件
  10. JS一些语法