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 ...
随机推荐
- jsp相关笔记(二)
在jsp中将数据库表格内容读出为一个表格,并在表格中添加超链接: <%@ page language="java" contentType="text/html; ...
- Robot Framework浏览器驱动下载
运行robot framework 有时打不开浏览器,可能用到的驱动不对,以下是各浏览器驱动下载,仅供参考!~ 各浏览器下载地址: Firefox浏览器驱动:geckodriver https: ...
- CentOS 7 Redis 内网 安装 卸载
# 不能连接外网, 安装Redis服务器的过程 https://redis.io/download (官网下载安装包, 最新版) redis-*.tar.gz 放在安装目录/usr/local/red ...
- 地址重写 No input file specified的解决方法
转载自:http://blog.csdn.net/williamsblog/article/details/37532737 (一)IIS Noinput file specified 方法一:改PH ...
- 单色三角形(hdu-5072
单色三角形模型:空间里有n个点,任意三点不共线.每两个点之间都用红色或者黑色线段链接.如果一个三角形的三条边同色,责成这个三角形是单色三角形.对于给定的红色线段列表,找出单色三角形的个数. 分析:对于 ...
- 第34 memcached缓存
1.缓存数据库 缓存:将数据存储在内存中,只有当磁盘胜任不了的时候,才会启用缓存. 缺点:断电数据丢失(双电),用缓存存储数据的目的只是为了应付大并发的业务,至于数据存储及可靠性不要找他了. 数据 ...
- 跨域访问问题js
您可以通过使用JSONP形式的回调函数来加载其他网域的JSON数据 访问百度的地址解析 返回来省,地区,市 $.getJSON("http://api.map.baidu.com/clou ...
- 卷积(转自wiki百科)
维基百科,自由的百科全书 图示两个方形脉冲波的卷积.其中函数 "g" 首先对 反射,接着平移 "t" ,成为 .那么重叠部份的面积就相当于 "t& ...
- 23.HashMap
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-value总是会当做一个整体来处理,系统会根据 ...
- Vuejs——(1)入门(单向绑定、双向绑定、列表渲染、响应函数)
版权声明:出处http://blog.csdn.net/qq20004604 目录(?)[+] 参照链接: http://cn.vuejs.org/guide/index.html [起步]部 ...