级别: ★★☆☆☆
作者: WYW https://www.jianshu.com/u/2f31928b08bf
审校: QiShare 团队 https://www.jianshu.com/c/b3bd94559163
笔者最近看了关于 Python 的部分内容, 发现网络编程部分非常容易能够创建一个本地 TCP 服务器, 正好可以用来分析一下 TCP 的请求和响应过程. 在本篇文章, 笔者将给大家介绍下 TCP 建立连接 (三次握手), 传输数据, 断开连接(四次挥手) 的过程.
TCP 简介
TCP https://baike.so.com/doc/3381795-3560272.html :TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的, 可靠的, 基于字节流的传输层通信协议, 由 IETF 的 RFC 793 https://tools.ietf.org/html/rfc793 定义.
聊到网络协议, 我们常常会想到 OSI https://baike.so.com/doc/5399194-5636680.html (Open System Interconnection 开放式系统互联)七层模型, TCP/IP 协议簇 https://baike.so.com/doc/1888584-1998203.html , 她位于 OSI,TCP/IP 协议簇哪一层等问题. 如下图 OSI 七层模型及对应的 TCP/IP 协议簇所示, TCP 位于 OSI 中的第四层(传输层). 位于 TCP/IP 协议簇中的第四层(TCP or UDP).
下图为 OSI 七层模型及对应的 TCP/IP 协议簇
TCP 是面向连接的, 是指客户端在发送, 接收数据之前需要先建立连接, 这个连接过程需要三次握手来完成, 笔者借助 Python 搭建了一个本地的 TCP 服务, 并使用 Wireshark https://baike.so.com/doc/5411758-5649873.html (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))
上述代码的效果如下图所示:
如上图, Got connection from ('127.0.0.1', 62515)我们可以确定客户端使用的端口是 59006.
通过上述准备工作, 下边笔者会使用 Wireshark 捕获 TCP 请求响应的整个过程, 并进行相应分析.
- QiShare(简书) https://www.jianshu.com/u/3db23baa08c7
- QiShare(掘金)
- QiShare(知乎) https://www.zhihu.com/people/edit
- QiShare(GitHub) https://github.com/QiShare
- QiShare(CocoaChina) http://www.cocoachina.com/bbs/u.php?tid=658244
- QiShare(Stack Overflow) https://stackoverflow.com/users/10118400/qishare
- QiShare(微信公众号)
来源: https://juejin.im/post/5c45a694e51d45518d46fa16