TCP编程实践小结1
说起TCP/IP协议,大家估计都能说出个一二,但是估计很少有人能够深入的理解这个协议,原因有这么几个:
- 协议本身确实复杂
- 入门教材没选对,太抽象了,导致大家浅尝辄止
- 学习过程中如果没有配合实践理解,过段时间也忘记了。
所以本篇文章的用意就是通过理论和实践的结合,加深大家对TCP协议的理解,更好的应用TCP来编写客户端和服务端。
TCP理论介绍
说到入门教材我比较推荐《图解TCP/IP》,本节内容也是在这本书的理论基础上结合自己的理解构成。
首先 TCP位于七层协议中的传输层。

TCP通信简单的说是类似这样的。

TCP协议是构建在网络层的IP协议之上的面向连接的、可靠的流协议。
TCP如何保证可靠性?
推荐使用WireShark抓包来学习TCP协议的特点,推荐一篇教程。由于HTTP协议是构建TCP协议之上的,所以可以用Wireshark对你的上网过程进行抓包,来观察TCP协议的流程和特性。
连接管理(三次握手)

上图是在HTTP GET之前,先经过了TCP的三次握手。
192.168.5.81 ——》 191.0.0.1 SYN(发起连接)
191.0.0.1 ——》 192.168.5.81 ACK(对192.168.5.81 的SYN的确认)+SYN(发起连接)
192.168.5.81 ——》 191.0.0.1 ACK(对191.0.0.1 的SYN的确认)
通过序列号与确认应答提高可靠性。

红圈部分是做个示例,TCP中的每一包数据都包含着自身的数据序列号(Sequence Number),以及已收到对方数据的确认号(Acknowledgement Number)。
以下是TCP的报文头定义,方便对照WireShark查看。

假如某包数据发送之后,迟迟未受到对方确认,则会进行超时重发。
假如重发一定次数之后,还是没有任何确认应答返回,就会判断网络或对端主机发生异常,强制关闭连接。
通过以上这个机制就可以保证数据不会存在丢包、顺序混乱的问题。
TCP以段为单位发送数据
参考Wireshark的截图,第一包数据中有个属性 MSS=1460(Maximum Segment Size最大消息长度,也就是所谓的“段”)。
以太网标准MSS是1460,同时两端的主机在发出建立连接的请求时会在TCP首部写入MSS选项,告诉对方自己的接口能够适应的MSS的大小。然后会在两者之间选择一个较小的值投入使用。
利用窗口控制提高速度 和 拥塞控制
TCP以段为单位收发数据,如果每发一个段都要进行确认的话效率有点低,于是TCP引入了窗口的概念。
窗口的大小就是指无需等待确认应答而可以继续发送数据的最大值。
在通信刚开始的时候窗口大小一般为1个段,后续随着通信的正常进行,窗口会变大,这叫做拥塞控制,主要是防止网络拥堵。因为计算机网络处在一个共享的环境中,如果大家一开始都采用最大量数据发送可能导致网络瘫痪。
下图红圈是每一个窗口确认的过程,可以看出来窗口是持续增大的。

流控制
TCP的流控制的意思就是通信双方会协商好传输数据的速度,否则一方数据发送太快,另一方数据处理能力有限就会导致数据丢弃,从而造成流量的浪费。
接收主机将自己可以接受的缓冲区大小放入到TCP首部字段通知给发送端。这个字段越大,说明网络的吞吐量越大。
OK,以上是TCP的一些基本概念和特性,讲的比较浅,算是自己的一个总结,说多了也不容易记住。
本篇文章先到这里,下一篇再介绍Socket API及其相关使用问题。
TCP编程实践小结1的更多相关文章
- Socket编程实践(6) --TCP服务端注意事项
僵尸进程处理 1)通过忽略SIGCHLD信号,避免僵尸进程 在server端代码中添加 signal(SIGCHLD, SIG_IGN); 2)通过wait/waitpid方法,解决僵尸进程 sign ...
- C# socket编程实践
C# socket编程实践——支持广播的简单socket服务器 在上篇博客简单理解socket写完之后我就希望写出一个websocket的服务器了,但是一路困难重重,还是从基础开始吧,先搞定C# ...
- [Python] 网络编程之TCP编程
转自:TCP编程 - 廖雪峰的官方网站 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协 ...
- 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤
福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 Java全栈大联盟 ...
- Socket编程实践(6) --TCPNotes服务器
僵尸进程过程 1)通过忽略SIGCHLD信号,避免僵尸进程 在server端代码中加入 signal(SIGCHLD, SIG_IGN); 2)通过wait/waitpid方法.解决僵尸进程 sign ...
- 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践
参考高性能javascript 理解浏览器UI线程 用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程 UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...
- 高性能JavaScript 编程实践
前言 最近在翻<高性能JavaScript>这本书(2010年版 丁琛译),感觉可能是因为浏览器引擎的改进或是其他原因,书中有些原本能提高性能的代码在最新的浏览器中已经失效.但是有些章节的 ...
- Java TCP编程
Java编写TCP编程--回射信息实例 注:简单的tcp联系,还存在问题,readUTF()为阻塞型,如果之前的用户一直不输入,则一直阻塞,之后的用户再连接会出现问题. import java.io. ...
- Method Swizzling和AOP(面向切面编程)实践
Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...
随机推荐
- Failed to connect to 127.0.0.1 port 1080: Connection refused package 问题解决方法
错误: fatal: unable to access 'https://github.com/******': Failed to connect to 127.0.0.1 port 1080: C ...
- CSS的六大选择器
选择器:选择器是一种模式,用于选择需要添加样式的元素. 首先简述六大选择器 基本选择器 标签选择器 类选择器 ID选择器 高级选择器 层次选择器 结构伪类选择器 属性选择器 其中基本选择器与层次选择器 ...
- Python:每日一题001
题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? **程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 个人解 ...
- Gym - 100781G-Goblin Garden Guards
题目链接:https://nanti.jisuanke.com/t/28882 解题思路:单纯的判断点是否在圆内,一一遍历圆外切正方形内的点即可,注意,该题要建个结构体数组存每个地精的位置,再bool ...
- Zookeeper Client基础操作和Java调用
## Zookeeper > Zookeeper目前用来做数据同步,再各个服务之前同步关键信息 i.客户端操作 1. 创建 create [-s] [-e] path data acl -s 为 ...
- 手机端table表格bug
table表格在手机端有一个小小的bug,就是td有一个右边线,解决办法可已给tr加一个背景色就行,或者table都行,完美解决
- http协议基本原理
HTTP(HyperText Transport Protocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议采用了请求/响应模型 ...
- ABP框架系列之五:(Unit Of Work-工作单元)
Introduction Connection and transaction management is one of the most important concepts in an appli ...
- python函数(一)
python函数(一) 1.函数的定义: def test(): print('test is running...') return 定义一个函数,有3个部分需要注意: 函数名称.函数的命名规范与变 ...
- $q的基本用法
angularjs的http是异步的没有同步,一般都会遇到一个场景,会把异步请求的参数作为条件执行下一个函数,之前一直在看其他人的博客理论太多看了很久才看懂 http({ method:'post', ...