初探TCP

级别: ★★☆☆☆
标签:「TCP」「三次握手」「数据传输」「四次挥手」
作者: WYW
审校: QiShare团队

笔者最近看了关于Python的部分内容,发现网络编程部分非常容易能够创建一个本地TCP服务器,正好可以用来分析一下TCP的请求和响应过程。
在本篇文章,笔者将给大家介绍下TCP建立连接(三次握手),传输数据,断开连接(四次挥手)的过程。

TCP简介

  • TCP:TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的可靠的基于字节流传输层通信协议,由IETF的RFC 793定义。

  • 聊到网络协议,我们常常会想到OSI(Open System Interconnection 开放式系统互联)七层模型、TCP/IP协议簇,她位于OSI、TCP/IP协议簇哪一层等问题。
    如下图OSI七层模型及对应的TCP/IP协议簇所示,TCP位于OSI中的第四层(传输层)。位于TCP/IP协议簇中的第四层(TCP or UDP)。

下图为OSI七层模型及对应的TCP/IP协议簇

OSI TCP/IP Family
  • TCP是面向连接的,是指客户端在发送、接收数据之前需要先建立连接,这个连接过程需要三次握手来完成,笔者借助Python搭建了一个本地的TCP服务,并使用Wireshark(Wireshark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。
    捕获了本地的TCP服务器和TCP客户端之间请求响应的过程,带大家一起看一下建立连接(三次握手),传输数据,断开连接(四次挥手)的过程。

本地搭建TCP服务准备工作:

笔者在前文提到了要用Python创建一个本地TCP服务器,并且分析TCP的请求响应过程。这里笔者使用的是PythonIDE、Mac自带的终端简单创建了一个本地TCP服务端和客户端。

笔者会分析的过程如下:
-> 创建并且启动一个端口号为20000的TCP服务端
-> 创建客户端并和服务端建立连接(三次握手)
-> 客户端向服务端发送数据'AB'
-> 服务端到数据后给客户端发送数据'AB'
-> 服务端收到数据向客户端发送收到的数据(当前即'AB')
-> 客户端和服务端断开连接(四次挥手)
-> 使用Wireshark对建立连接(三次握手),传输数据,断开连接(四次挥手)的过程进行分析
服务端代码:

Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license()" for more information.
>>> from socketserver import BaseRequestHandler, TCPServer
>>> class EchoHandler(BaseRequestHandler):
    def handle(self):
        print('Got connection from', self.client_address)
        while True:
            msg = self.request.recv(8192)
            if not msg:
                break
            self.request.send(msg)

            
>>> if __name__ == '__main__':
    serv = TCPServer(('', 20000), EchoHandler)
    serv.serve_forever()

    
Got connection from ('127.0.0.1', 59006)

客户端代码:

wangyongwangdeiMac:~ wangyongwang$ python
Python 2.7.15 (default, Oct  2 2018, 11:47:18) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import socket, AF_INET, SOCK_STREAM
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.connect(('localhost', 20000))

上述代码的效果如下图所示:


TCP请求响应效果图
TCP建立连接效果图

如上图,Got connection from ('127.0.0.1', 62515)我们可以确定客户端使用的端口是59006

通过上述准备工作,下边笔者会使用Wireshark捕获TCP请求响应的整个过程,并进行相应分析。

TCP三次握手

  • TCP通过三次握手建立连接,我们对下图应该比较熟悉:


    TCP三次握手图解

对上图中的代号及下文中的代号做说明:

  • Seq即下文中的Sequence number ,序列号是指发送数据的位置。每发送一次数据,就累加一次该数据字节数的大小。一般用Wireshark捕获我们平时的请求的Seq是一个随机数。
  • AckAcknowledgement number,是指下一次应该受到的数据的序列号。
  • SYN为Flags部分的Syn,Syn为1表示希望建立连接。
  • ACK为Flags部分的ACK,Ack为1表示确认应答的字段变为有效。

TCP第一次握手,客户端向服务端发送报文,关键信息为Syn=1,Seq=0。如下图所示,sequence number= x = 0,Syn=1。


TCP第一次握手

TCP第二次握手,服务端向客户端发送报文,关键信息为Ack=x+1=1,Syn=1,Seq=y=0。如下图所示,sequence number=y=0,Ack=x+1=1 , Syn = 1。


TCP第二次握手

TCP第三次握手,客户端向服务端发送报文,Seq=x+1=1,Ack=y+1=1,ACK=1。如下图所示,Seq=x+1=1,Ack=y+1=1,ACK=1。


TCP第三次握手

我们可以发现在三次握手之后,还有一次TCP Window Update。


TCP Window Update

TCP Window Update 是TCP通信中的一个状态,它可以发生的原因有很多,但最终归结于发送者传输数据的速度比接收者读取的数据还快,这使得接受端的在缓冲区必须释放一部分空间来装发送过来的数据,然后向发送者发送Windows Update,告诉给发送者应该以多大的速度发送数据,从而使得数据传输与接受恢复正常。参考:tcp三次握手

从上图TCP Window Update,根据Source Port:20000及Destination Port:59006可知,当前发送者是客户端,解释下上一段文字的意思是,客户端发送的数据太快,服务端读书数据慢,服务端向客户端发送了一个TCP Window Update的报文。

上述内容就是TCP建立连接的过程,下边笔者给大家介绍下传输数据部分的内容:

TCP的数据传输过程:

查看数据传输过程和之前建立连接部分,用的是下图代码进行的分析:


代码内容和之前建立连接的代码一样,只是添加了发送数据断开连接的几行代码。可见这次客户端分配的端口号为53262
在分析数据传输过程之前,笔者先对下边会用到的名词及工具做个简单说明:

字节byte比特bit,1个字节(byte)=8个比特(bit)。

ASCII码:是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统

ASCII码对照表

举个例子'A'的ASCII码为0x41

基本的16进制、2进制、10进制之间的转换

16进制0x41对应2进制为 0100 0001对应10进制为4 * 16 + 1 = 65

在线进制转换

下边笔者带大家看一下数据传输部分的分析:

下图表示客户端s.send(b'A')以二进制形式传输'A'(其对应的ASCII码为65)传输过程,:

客户端到服务端

下边展示一个客户端s.send(b'AB')并且服务端给予相应的回应(服务端也给客户端发送收到的'')的过程

  • 接收数据的部分Flags中的Acknowledgement 设置为1,表示确认应答的字段有效
  • 接收数据的部分Flags中的Push 设置为1表示表示接收方应该尽快把数据传给上层应用协议

源端口53262目的端口20000可以看出,下图表示客户端向服务端发送消息,发送的数据为'AB','AB'的ASCII码为0x4142。

客户端向服务端发送消息

源端口20000目的端口53262可以看出下图表示服务端向客户端反馈收到了消息。Acknowledgement number 为4是因为,服务端接接收了客户端的2个字节的数据,在之前的客户端的Sequence number的基础上加了2。
服务端到客户端收到消息响应

源端口20000目的端口53262可以看出,下图表示服务端向客户端发送消息,发送的数据为'AB','AB'的ASCII码为0x4142。
服务端给客户端发送消息

源端口53262目的端口20000可以看出下图表示客户端向服务端反馈收到了消息。Acknowledgement number 为4是因为,客户端接收了服务端的2个字节的数据,在之前的服务端的Sequence number的基础上加了2。
客户端收到服务端消息后的响应

TCP断开连接四次挥手

TCP断开连接示意图如下:


TCP断开连接示意图

对应的Python的客户端代码s.shutdown(2),客户端主动断开连接的。

  • 断开连接的Flags中Fin是设置为1的,表示希望断开连接。
  • 断开连接的Flags中Ack是设置为1的,表示确认应答字段有效。

响应的Wireshark抓包分析如下:
TCP断开连接第一次挥手,从源端口53262到目的端口20000,可以看出是客户端主动断开连接的。Flags中的Fin是设置为1的,Sequence number为7。

TCP断开连接第一次挥手

TCP断开连接第二次挥手,从源端口20000到目的端口53262,可以看出是服务端给予客户端断开连接的响应。并且Acknowledge number对之前的客户端的Sequence number做了加1操作。

TCP断开连接第二次挥手

TCP断开连接第三次挥手,从源端口20000到目的端口53262,Flags中的Fin是设置为1的,可以看出是服务端向客户端发送断开连接的。Sequence number为7。
TCP断开连接第三次挥手

TCP断开连接第四次挥手,从源端口53262到目的端口20000,可以看出是客户端给予服务端断开连接的响应。并且Acknowledge number对之前的服务端的Sequence number做了加1操作。
TCP断开连接第四次挥手

下边,笔者贴出了IP和TCP首部及Wireshark捕获TCP请求过程的的图。有兴趣的读者可自行做简单分析。

TCP数据在IP数据报中的封装及TCP包首部

  • 后来和昆哥一起交流,经过昆哥指正,上图的TCP首部已经更新过了,较新的TCP首部格式如下:


    TCP首部

    下图为TCP首部中的控制位部分


    控制位 Control Flag
TCP
TCP

参考内容:


了解更多iOS及相关新技术,请关注我们的公众号:

小编微信:可加并拉入《QiShare技术交流群》。

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
初探TCP
初探IP、UDP
iOS 多线程之线程安全
iOS 多线程之GCD
iOS 多线程之NSOperation
iOS 多线程之NSThread
iOS Winding Rules 缠绕规则
奇舞周刊

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265