HTTP,TCP的长连接和短连接以及socket( 二 )


3.3 TCP长连接
接下来我们再模拟一下长连接的情况 , client向server发起连接 , server接受client连接 , 双方建立连接 。Client与server完成一次读写之后 , 它们之间的连接并不会主动关闭 , 后续的读写操作会继续使用这个连接 。
首先说一下TCP/IP详解上讲到的TCP保活功能 , 保活功能主要为服务器应用提供 , 服务器应用希望知道客户主机是否崩溃 , 从而可以代表客户使用资源 。如果客户已经消失 , 使得服务器上保留一个半开放的连接 , 而服务器又在等待来自客户端的数据 , 则服务器将应远等待客户端的数据 , 保活功能就是试图在服务 器端检测到这种半开放的连接 。
如果一个给定的连接在两小时内没有任何的动作 , 则服务器就向客户发一个探测报文段 , 客户主机必须处于以下4个状态之一:

  1. 客户主机依然正常运行 , 并从服务器可达 。客户的TCP响应正常 , 而服务器也知道对方是正常的 , 服务器在两小时后将保活定时器复位 。
  2. 客户主机已经崩溃 , 并且关闭或者正在重新启动 。在任何一种情况下 , 客户的TCP都没有响应 。服务端将不能收到对探测的响应 , 并在75秒后超时 。服务器总共发送10个这样的探测  , 每个间隔75秒 。如果服务器没有收到一个响应 , 它就认为客户主机已经关闭并终止连接 。
  3. 客户主机崩溃并已经重新启动 。服务器将收到一个对其保活探测的响应 , 这个响应是一个复位 , 使得服务器终止这个连接 。
  4. 客户机正常运行 , 但是服务器不可达 , 这种情况与2类似 , TCP能发现的就是没有收到探查的响应 。
4. 长连接和短连接的优点和缺点
由上可以看出 , 长连接可以省去较多的TCP建立和关闭的操作 , 减少浪费 , 节约时间 。对于频繁请求资源的客户来说 , 较适用长连接 。不过这里存在一个问题 , 存活功能的探测周期太长 , 还有就是它只是探测TCP连接的存活 , 属于比较斯文的做法 , 遇到恶意的连接时 , 保活功能就不够使了 。在长连接的应用场景下 , client端一般不会主动关闭它们之间的连接 , Client与server之间的连接如果一直不关闭的话 , 会存在一个问题 , 随着客户端连接越来越多 , server早晚有扛不住的时候 , 这时候server端需要采取一些策略 , 如关闭一些长时间没有读写事件发生的连接 , 这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度 , 限制每个客户端的最大长连接数 , 这样可以完全避免某个蛋疼的客户端连累后端服务 。
短连接对于服务器来说管理较为简单 , 存在的连接都是有用的连接 , 不需要额外的控制手段 。但如果客户请求频繁 , 将在TCP的建立和关闭操作上浪费时间和带宽 。
长连接和短连接的产生在于client和server采取的关闭策略 , 具体的应用场景采用具体的策略 , 没有十全十美的选择 , 只有合适的选择 。
长连接多用于操作频繁 , 点对点的通讯 , 而且连接数不能太多情况 ,  。每个TCP连接都需要三步握手 , 这需要时间 , 如果每个操作都是先连接 , 再操作的话那么处理速度会降低很多 , 所以每个操作完后都不断开 , 次处理时直接发送数据包就OK了 , 不用建立TCP连接 。例如:数据库的连接用长连接 ,  如果用短连接频繁的通信会造成socket错误 , 而且频繁的socket 创建也是对资源的浪费 。
而像WEB网站的http服务一般都用短链接 , 因为长连接对于服务端来说会耗费一定的资源 , 而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源 , 如果用长连接 , 而且同时有成千上万的用户 , 如果每个用户都占用一个连接的话 , 那可想而知吧 。所以并发量大 , 但每个用户无需频繁操作情况下需用短连好 。
5、容易混淆的概念——TCP的keep alive和HTTP的Keep-alive


推荐阅读