高性能网络编程1----accept建立连接

转 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时间片,使得线程能够及时的做其他工作。

时间: 2024-10-21 21:58:49

高性能网络编程1----accept建立连接的相关文章

高性能网络编程(1)—accept建立连接?(转载,作者:陶辉)

编 写服务器时,许多程序员习惯于使用高层次的组件.中间件(例如OO(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发 的效率,追求更快的完成项目功能点.希望应用代码完全不关心通讯细节.他们更喜欢在OO世界里,去实现某个接口.实现这个组件预定义的各种模式.设置组件 参数来达到目的.学习复杂的通讯框架.底层细节,在习惯于使用OO语言的程序员眼里是绝对事倍功半的.以上做法无可厚非,但有一定的局限性,本文讲述的网 络编程头前冠以“高性能”,它是指程序员设计编写的服务器需要

高性能网络编程技术

高性能网络编程技术 作者:jmz (360电商技术组) 如何使网络服务器能够处理数以万计的客户端连接,这个问题被称为C10K Problem.在很多系统中,网络框架的性能直接决定了系统的整体性能,因此研究解决高性能网络编程框架问题具有十分重要的意义. 1. 网络编程模型 在C10K Problem中,给出了一些常见的解决大量并发连接的方案和模型,在此根据自己理解去除了一些不实际的方案,并做了一些整理. 1.1.PPC/TPC模型 典型的Apache模型(Process Per Connectio

高性能网络编程 - select系统调用

IO复用使得程序能够同时监听多个文件描述符,比如客户端需要同时处理用户输入和网络连接,服务器端需要同时处理监听套接字和连接套接字,select系统调用可以使得我们监听自己感兴趣描述符,可读,可写,异常等事件.select能处理的异常只有带外数据.能同时处理描述符的数量受限于FD_SETSIZE的大小(一般1024).下面这个程序展示了它的一般用法. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #i

Linux Socket过程详细解释(包括三次握手建立连接,四次握手断开连接)

我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web 服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型 有哪些?还有socket的基本函数,这些都是本文想介绍的.本文的主要内容如下: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().

Socket过程详细解释(包括三次握手建立连接,四次握手断开连接)

本文的主要内容如下: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().connect()函数 3.4.accept()函数 3.5.read().write()函数等 3.6.close()函数 4.socket中TCP的三次握手建立连接详解 5.socket中TCP的四次握手释放连接详解 6.一个例子(实践一下) 7.留下一个问题,欢迎大家回帖回答!!! 1.网络中进程之间如何

tcp/udp建立连接并通信的过程

基于TCP的socket编程的服务器程序流程如下: 1.创建套接字 SOCKETsockSrv = socket(AF_INET, SOCK_STREAM, 0) ; 2.将套接字绑定到本地地址和端口上 SOCKADDR_INaddrSrv ; addrSrv.sin_addr.S_un.S_addr =htonl(INADDR_ANY) ;                   //把一个u_long类型的值转化为网络字节顺序 addrSrv.sin_family = AF_INET ; add

【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上篇请见:<高性能网络编程(二):上一个10年,著名的C10K并发连接问题>).本文将讨论单机服务器实现C10M(即单机千万并发连接)的可能性及其思路. 截至目前,40gpbs.32-cores.256G RAM的X86服务器在Newegg网站上的报价是几千美元.实际上以这样的硬件配置来看,它完全可

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

阅读(81374) | 评论(9)收藏16 淘帖1 赞3 JackJiang Lv.9    1 年前 | 前言 曾几何时我们还在寻求网络编程中C10K问题(有关C10K问题请见文章<The C10K problem(英文在线阅读.英文PDF版下载.中文译文)>)的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了. 我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用户基数的互联网公司,往往面临的并发

一文读懂高性能网络编程中的I/O模型

1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱. 限于篇幅原因,请将本文与<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>连起来读,这样会让知识更连贯. 学习交流: - 即时通讯开发交流3群:185926912[推荐] - 移动端IM