【Python与AI基础】Python编程基础:网络通信与Socket

57 阅读8分钟

【Python与AI基础】Python编程基础:网络通信与Socket

www.bilibili.com/video/BV1oe…

一、TCP/IP协议
1、什么是协议

我们来看看这样一串数字:510101198812105379,相信每一个中国人对长成这样的数字串并不陌生,没错,这是中国公民的身份证号码。但是,老外看到这一串数字,估计就懵了,除了能看出是一串数字外估计看不出什么别的名堂了。为什么?因为这串数字是中国基于1999年7月1日实施的GB11643-1999公民身份证号码标准,中国老百姓经常使用身份证,所以对这一串数字已经很熟悉了。

另外,为什么中国人无法与老外进行语言上的沟通?是因为我们说的是普通话,而老外说的是外国话,它们的语法规则,发音,写法都不一样。全世界的人民要能完全互相交流,那么只要60亿人都说一门语言不是就可以了吗。

协议就是这样一种东西,它定义了一个规范或者规则,供人们去遵守,如果大家都遵守这样一种规范,便可以互相交流,互相通信,网络系统也不例外。众所周知,现在能够接入网络的设备越来越丰富,比如手机,电脑,电话,蓝牙,WIFI,GPS等,并且生产这些设备的的厂商也非常多,如何能保证不同厂商生产的不同设备都可以互相进行通信呢?我们需要定义一致的规范,只要大家共同去遵守,就可以达到这一目的。

比如,对于身份证号码,我们不单能看出这串数字是身份证号码,还能知道该身份证号码对应的这个人的基本信息,如出生地,性别,年龄等,为什么?因为GB11643-1999这份标准明确地定义了身份证号码每一位所代表的意义:

前2位表示所在的省份,31表示上海市,32表示江苏省。

第3、4位表示所在地市,如3205表示江苏省苏州市。

第5、6位表示所在区县,310101表示上海市黄埔区。

第7~14位表示出生年月日,上述身份证号码代表出生日期为1988年12月10日。

第15、16位表示所在地派出所编号。

第17位表示性别,奇数为男,偶数为女

第18位为检验码,用于验证身份证的正确性。

上述这一段话就是一种规范,310101198812105338这个号码就是这种规范的一种实例。

网络协议其实也是这样一种规范,在网络传输过程上传递的都是二进制数据,该数据如果没有一种规范定义清楚,当数据接收端接收到该数据包时,只能认为是一种天书,就像老外看中国公民身份证号码一样。网络协议无非就在定义某一个数据包的数据规则,某一位代表什么,某一位代表什么,与身份证号码的定义规则如出一辙。

在电影“智取威虎山”中,主演扬子荣与土匪之间有一段经典对白,其实也是一种协议的体现:

土匪:蘑菇,你哪路?什么价?(什么人?到哪里去?) 
杨子荣:哈!想啥来啥,想吃奶来了妈妈,想娘家的人,孩子他舅舅来了。(找同行) 
杨子荣:拜见三爷! 
土匪:天王盖地虎!(你好大的胆!敢来气你的祖宗?) 
杨子荣:宝塔镇河妖!(要是那样,叫我从山上摔死,掉河里淹死。) 
土匪:野鸡闷头钻,哪能上天王山!(你不是正牌的。) 
杨子荣:地上有的是米,喂呀,有根底!(老子是正牌的,老牌的。) 
土匪:拜见过阿妈啦?(你从小拜谁为师?) 
杨子荣:他房上没瓦,非否非,否非否!(不到正堂不能说。) 
土匪:嘛哈嘛哈?(以前独干吗?) 
杨子荣:正晌午说话,谁还没有家?(许大马棒山上。) 
土匪:好叭哒!(内行,是把老手) 
杨子荣:天下大耷拉!(不吹牛,闯过大队头。) 
座山雕:脸红什么? 
杨子荣:精神焕发! 
座山雕:怎么又黄了? 
杨子荣:防冷,涂的蜡! 
座山雕:晒哒晒哒。(谁指点你来的?) 
杨子荣:一座玲珑塔,面向青寨背靠沙!(是个道人。)
2、OSI七层模型
第七层应用层Application
第六层表示层Presentation
第五层会话层Session
第四层传输层Transport
第三层网络层Network
第二层数据链路层Data Link
第一层物理层Physical
3、TCP/IP模型
OSI模型TCP/IP模型
第七层应用层Application应用层
第六层表示层Presentation
第五层会话层Session
第四层传输层Transport传输层
第三层网络层Network网络层
第二层数据链路层Data Link访问层
第一层物理层Physical
4、TCP协议

TCP协议提供了一种端到端的、基于连接的、可靠的通信服务。之所以说它可靠,首先是因为每一个TCP连接都会在发送端和接收端之间产生三次预先通讯,用术语来说就是TCP的三次握手(Handshake),三次握手的过程会在稍微后面提到。

它负责确定一个TCP连接,并且负责数据包的发送确认和发送的次序,同时负责重新传送在传输过程中破坏或者丢失的数据包;它能够对成功接收的数据包进行回应,可以测试所接收数据包的完整性,并把接收到的次序错乱的数据包进行顺序整理,这些是TCP通讯可靠性的另一个方面。

由于TCP是用户应用和诸多网络协议之间的纽带,因此TCP必须能够同时接收多个应用的数据,并且必须具备跟踪记录到达的数据包需要转发到的应用程序的功能,这个功能是通过端口来实现的。

对于端口,相信使用只要是上网的人一定不会陌生这个词,在很多的文章、软件中广泛使用到了这个词汇,但是相信也有不少人对“端口”这个词是知其然不知其所以然的。端口的作用在上面已经说到了,这里要进行深入了解的话,需要介绍一下TCP协议数据包头的结构。如图所示。

1.png

5、TCP三次握手

谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立,并且任何一个连接过程的建立通常都是由客户端发起请求,而服务器端通常扮演被动响应。另外,这个过程之所以需要三次来完成,是为了保证传输的可靠性,由于客户端和服务器端互相并不知道对方,那么如何保证连接的可靠呢?那一定需要双方共同的确认很多信息。

2.png

6、TCP四次挥手

所谓四次挥手,即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。这一过程由客户端(主动方)或服务端(被动方)任一方执行close来触发,整个流程如下图所示。

3.png

7、IP协议

IP协议负责将数据包切割成一小块一小块的,然后每个数据包都加上一个目的地地址,并且通过选择一定的路径发送出去,最后到达目的地以后又重新把一个个的小数据包合并成一个完整的数据。在一个IP数据包中需要包含很丰富的信息,这其中包括:

4.png

7、Socket

针对 TCP/IP 协议簇进行的程序封装,在Windows/Linux均有这样底层模块。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

二、模拟客户端与服务器

先运行TestSocket模拟工具,然后分别用Python代码模拟客户端与服务器端并发送消息。

import socket
# 定义一个客户端连接
def test_client():
    # 建立与服务器的连接
    s = socket.socket()     # 此类实例的方式,默认使用TCP协议
    s.connect(('192.168.112.130', 554))
    # 传输数据(收发数据包)
    content = "Welcome to Woniu College 这是蜗牛学院"
    s.send(content.encode('gbk'))
    # 关闭连接
    s.close()
# test_client()
# 定义一个服务器端
def test_server():
    s = socket.socket()
    s.bind(('192.168.112.1', 555))  # 绑定服务器端IP和端口号
    s.listen()                      # 保持对555端口的监听
    while True:
        chanel, client = s.accept()     # 接收来自客户端的数据
        message = chanel.recv(1024)
        print(message.decode())
test_server()

在通信过程中,使用Wireshark,可以完整监控到整个通信过程。

5.png