从三次握手的细节说起

刚开始尝试使用java等后端语言写IO流,或用套接字(socket)实现简单C/S通信的同学们,常常会接触到的一个概念:就是所谓的“三次握手”,socket作为一个API接口,封装了TCP/IP通信的细节,使我们只需要调用简单的接口而无需关心具体的实现,那么

Socket三次握手的细节是如何实现的?

三次握手的过程实际上就是相互抛/接(3次)包的过程

三次握手的过程:

  1. 客户端抛 --> SYN包(建立连接包) --> 服务器接收
  2. 服务器抛 --> ACK包(确认应答包)和SYN包 --> 客户端接收
  3. 客户端抛 --> ACK包(确认应答包) --> 服务器接收

建立连接后客户端便可从服务器接收数据包进行通信

注意:三次握手时抛/接的包和连接建立后收发的数据包是不同的!前者是只携带有TCP报文和IP报文头部的包,不携带具体的数据内容,而后者除了TCP和IP报文头部还携带了具体的数据

建立连接后的通信过程:

l  发送端  -->   数据包  -->  接收端

l  接收端  -->  ACK确认应答  --> 发送端

TCP是全双工通信:

这里的发送端/接收端可以是客户端/服务器,也可以是服务器/客户端,因为TCP通信是全双工通信,所以建立连接后可以同时进行以下两个过程:

A.   客户端 --> 数据包 --> 服务器 --> ACK应答 --> 客户端

B.   服务器 --> 数据包 --> 客户端 --> ACK应答 --> 服务器

ACK包/FIN包/SYN包的具体组成:

如下图三次握手时交换包的具体组成:TCP首部+IP首部(无具体数据内容!)

建立连接后收发数据包的具体组成:

(TCP首部+IP首部+具体数据)

TCP通信的单位——段

TCP通信以段为单位,段由TCP数据和TCP首部组成

如果再将网络层的IP协议考虑进去的话,TCP/IP通信以IP分组为单位

IP分组=TCP段+IP首部=(TCP数据+TCP首部)+IP首部

注:TCP首部也算是IP数据包的一部分

TCP的"串行式"连接和"管道式"连接

A.TCP“串行式”连接

建立连接后,最简单的TCP通行是串行进行的,单次通信发送端只能发送一个段。只有在接收到接收端发来的ACK应答包前,才能将第二个段发出去,这段时间内发送端只能空等待

B.TCP“管道式”连接

很显然,串行通信效率很低,所以我们想,能不能在第一个段发送出去后,无需等待ACK应答的返回就发送第二个段呢?这样效率不就提高了吗?基于这个理念人们提出了窗口的概念:

窗口:无需等待ACK应答的返回就可以连续发送的段的数量的最大值

上图中,窗口大小为4,段的发送就好像管道一般,窗口大小就好比是“管道”的流量

TCP连接对HTTP事务处理性能的影响

HTTP作为一种应用层协议,其事务处理要依赖于传输层的TCP协议机制的运作,所以HTTP事务处理的性能瓶颈很大程度上来源于TCP连接,体现在下面几点:

  • TCP连接时间的消耗
  • TCP的慢启动机制
  • TCP采用的Nagle算法

每次TCP连接带来的时延是HTTP时延的重要来源

解决方法:采用HTTP持久连接技术消除多次连接的时延

TCP的慢启动机制

TCP慢启动机制体现在两方面:

a.限制初次启动时发送的段的数量:

上面提到了TCP窗口的概念,但TCP能不能一开始就发送窗口上限的段呢?答案是不能的,因为这会造成网络拥塞,为了避免这个问题,TCP采用了慢启动机制,一开始发送的段数为1,抛接完成后将段数上升为2,然后是4,再然后是8,段数将以指数形式递增,直到窗口大小的上限

b.设置慢启动阀值

由上图可以看到,当达到拥堵窗口的大小时,将导致超时重发,这时初次发送的段数又从1开始指数递增,不同的地方是:这时候设置了慢启动阀值(拥堵窗口的一半),发送的段数达到慢启动阀值时,将不再以指数形式上升,而是按一定的比例缓慢得直线上升

解决方法:正是因为单次TCP连接的时延和TCP的慢启动机制,HTTP的持久连接才显得尤为重要

Nagle算法

TCP协议本身并没有有规定发送单个段的数据包大小的最小值,那让我们想想,如果我们试图在单个段中发送几个字节的数据包会怎样呢?如果这样,TCP将通过Nagle算法的机制来提高网络利用率,很显然,将包含数据量极小的段都单独发出去将会极大降低网络利用率,所以通过Nagle算法,不直接派发小数据量的段,而是选择将它们绑定在一起,当达到要求尺寸后才派发出去,这造成了时间上的延迟。Nagle算法是一把双刃剑,它提高了网络利用率,但同时造成了TCP的时延

解决方法:Nagle是可以选择关闭的,当然,前提是你得在TCP通信中写入大块的数据

参考资料:

《HTTP权威指南》作者古尔利

《图解TCP/IP》作者竹下隆史

【学习笔记】TCP通信的细节及TCP连接对HTTP事务处理性能影响的更多相关文章

  1. 【计算机网络】TCP通信的细节及TCP连接对HTTP事务处理性能影响

    从三次握手的细节说起 刚开始尝试使用java等后端语言写IO流,或用套接字(socket)实现简单C/S通信的同学们,常常会接触到的一个概念:就是所谓的“三次握手”,socket作为一个API接口,封 ...

  2. Windows phone 8 学习笔记(3) 通信

    原文:Windows phone 8 学习笔记(3) 通信 Windows phone 8 可利用的数据通信方式比较广泛,在硬件支持的前提下,我们可以利用WiFi.蓝牙.临近感应等多种方式.数据交互一 ...

  3. TCP协议学习笔记(一)首部以及TCP的三次握手连接四次挥手断开

    TCP协议是一种面向连接的.可靠的流协议. 流即不间断的数据结构.这样能够保证接收到数据顺序与发送相同.但是犹如数据间没有间隔,因此在TCP通信中,发送端应用可以在自己所要发送的消息中设置一个标示长度 ...

  4. 《即时消息技术剖析与实战》学习笔记8——IM系统如何保证长连接的可用性:心跳机制

    假设有以下突发意外情况: 用户进入信号不好的地方,手机没有网络信号了 上网的路由器突然掉线了 这个时候,比如微信发消息,消息就会转圈圈,甚至变成红色叹号-- 上面情况都会导致"长连接&quo ...

  5. TCP/IP学习笔记16--TCP--特点,数据重发,连接管理,段

    TCP充分实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的包进行顺序控制,这些在UDP中都是没有的.UDP是一种没有复杂控制,提供面向无连接通信服务的一种协议.TCP是面向有 ...

  6. twisted 学习笔记二:创建一个简单TCP客户端

    #coding=utf-8 from twisted.internet import reactor,protocol class QuickClient(protocol.Protocol): de ...

  7. UNP学习笔记(第四章 基本TCP套接字编程)

    本章讲解编写一个完整的TCP客户/服务器程序所需要的基本套接字函数. socket函数 #include <sys/socket.h> int socket(int family,int ...

  8. Java学习笔记53(网络编程:TCP协议案例)

    简易的案例 客户端: package demo; import java.io.IOException; import java.io.InputStream; import java.io.Outp ...

  9. Adaptive AUTOSAR 学习笔记 12 - 通信管理

    本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本 AUTOSAR_EXP_PlatformDesign.pdf 缩写 CM:Communicatio ...

随机推荐

  1. secureCRT端口转发功能

    总共有三台机器: A是办公网络的windows主机, B是一台linux堡垒机(114.144.xxx.xx), C是内网生产环境一台linux机器(192.168.1.6), A只能访问B但A不能访 ...

  2. liunx下search文件内容的几种方式

    第一种.使用vim来search内容 /regex_word,从上到下匹配 ?regex_word,从下到上匹配 n是获取下一个匹配字符串,N是获取上一个匹配字符串. 第二种.使用grep命令 gre ...

  3. Angela Merkel poised for record poll win and historic third term

    Her success remains a mystery for many, but victory could see the German chancellor beat Thatcher's ...

  4. 微信小程序开发带来的思考

    若无小程序开发经验,可先阅读 玩转微信小程序 一文. 微信小程序正式上线已有几周时间,相信它的开发模式你已烂熟于胸,可能你也有所疑问,我竟能用 web 语言开发出如此流畅的几乎原生体验的应用.可能你又 ...

  5. groovy学习(三)range

    // 1900..1999 包含边界// 2000..<2100 不包含边界twentiethCentury = 1900..1999reverseTen = 10..1println(twen ...

  6. 归纳篇(一)CSS的position定位和float浮动

    近期会更新一系列博客,对基础知识再度做个巩固和梳理. 一.position定位 (一):position的属性 1.absolute:生成绝对定位的元素,相对于最近一级定位不是static的父元素来进 ...

  7. iOS使用StroryBoard页面跳转及传值

    之前在网上iOS的页面跳转大多都是按回以前的那种xib的形式,但鄙人是使用storyboard的.这篇就只介绍利用storyboard进行页面跳转与传值. 新建页面 iOS的程序也是使用了MVC的思想 ...

  8. JavaScript中数组Array方法详解

    ECMAScript 3在Array.prototype中定义了一些很有用的操作数组的函数,这意味着这些函数作为任何数组的方法都是可用的. 1.Array.join()方法 Array.join()方 ...

  9. Excel与XML相互转换 - C# 简单实现方案

    Excel与XML相互转换 - C# 简单实现方案 在日常工作中,我需要将数据存储在Excel中进行数据分析和处理,然后再将数据转换为XML格式进行跨平台的数据交换.网上搜索Excel转换为XML的实 ...

  10. 学习JVM--垃圾回收(二)GC收集器

    1. 前言 在上一篇文章中,介绍了JVM中垃圾回收的原理和算法.介绍了通过引用计数和对象可达性分析的算法来筛选出已经没有使用的对象,然后介绍了垃圾收集器中使用的三种收集算法:标记-清除.标记-整理.标 ...