Python网络编程概述

网络中的术语解释

名称 解释 那一层 说明
端口号 程序地址 传输层 区分同一计算机中不同的程序
IP地址 主机地址 网络层 识别不同的主机或者路由器
MAC地址 物理地址 数据链路层 在同一数据链路中识别不同的计算机
TCP 基于字节流协议 传输层 面向连接,可靠的基于字节流,有顺序的协议
UDP 基于数据报协议 传输层 面向非连接,不可靠的基于数据报的,无顺序的协议
HTTP 基于TCP的协议 应用层 超文本传输协议,基于TCP,需要建立连接

TCP和UDP的区别

是否连接:

TCP面向连接(发送数据之前需要建立连接,三次握手).UDP面向无连接的(发送数据无需先建立连接)

是否丢包重试

TCP实现了数据传输时的各种控制功能,可以进行丢包的重发机制,还可以对次序乱掉的分包进行顺序控制.
因此TCP传输的数据是可靠的.UDP不会进行丢包重试,也不会纠正到达的顺序,甚至发送之后,根本不关心对象有没有收到.它是不可靠的,不安全的.

传输模式

TCP采用的是流模式(面向字节流) UDP采用的是数据报模式(面向的是报文)

传输时两端的对应关系

TCP是一对一的关系,而UDP传输支持一对一,一对多,多对一,多对多的交互

可靠性

TCP全双工非常可靠,无差错,不丢失,且按序到达. UDP不保证可靠性,不保证顺序到达.

传输速度

TCP较慢,UDP叫较快

应用场合

TCP适用于对效率要求不高,但是对准确性要求相对高.或者是要求有连接的状况.
UDP适用于对效率要求较高,对准确性要求相对较低的场景.

应用示例

TCP一般应用于文件传输(HTTP,FTP,对数据的准确性要求较高,速度可以相对较慢)
发送和接收邮件(pop imap SMTP),远程登录(telnet SSH 对数据准确性有一定要求,有连接概念)
UDP一般应用于即时通信(QQ聊天) 在线视频,网络语音电话

面向连接和非面向连接的形象举例

面向连接的举例: 两个人打电话,首先是拨号对面应答之后才可以通信.
面向非连接的举例: 发送短信,只管发送,对面接收没有接收到,并不知道.

OSI七层模型

Python网络编程概述_第1张图片

这里我们只对OSI各层进行功能上的大概阐述,不详细深究,因为每一层实际都是一个复杂的层。后面我也会根据个人方向展开部分层的深入学习。这里我们就大概了解一下。我们从最顶层——应用层 开始介绍。整个过程以公司A和公司B的一次商业报价单发送为例子进行讲解。

应用层

OSI参考模型中最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP
实际公司A的老板就是我们所述的用户,而他要发送的商业报价单,就是应用层提供的一种网络服务,当然,老板也可以选择其他服务,比如说,发一份商业合同,发一份询价单,等等。

表示
表示层提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。如果必要,该层可提供一种标准表示形式,用于将计算机内部的多种数据格式转换成通信中采用的标准表示形式。数据压缩和加密也是表示层可提供的转换功能
由于公司A和公司B是不同国家的公司,他们之间的商定统一用英语作为交流的语言,所以此时表示层(公司的文秘),就是将应用层的传递信息转翻译成英语。同时为了防止别的公司看到,公司A的人也会对这份报价单做一些加密的处理。这就是表示的作用,将应用层的数据转换翻译等。

会话

会话层就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应
会话层的同事拿到表示层的同事转换后资料,(会话层的同事类似公司的外联部),会话层的同事那里可能会掌握本公司与其他好多公司的联系方式,这里公司就是实际传递过程中的实体。他们要管理本公司与外界好多公司的联系会话。当接收到表示层的数据后,会话层将会建立并记录本次会话,他首先要找到公司B的地址信息,然后将整份资料放进信封,并写上地址和联系方式。准备将资料寄出。等到确定公司B接收到此份报价单后,此次会话就算结束了,外联部的同事就会终止此次会话。

传输

传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。我们通常说的,TCP UDP就是在这一层。端口号既是这里的“传输层就相当于公司中的负责快递邮件收发的人,公司自己的投递员,他们负责将上一层的要寄出的资料投递到快递公司或邮局。

网络

本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一层就是我们经常说的IP协议层。IP协议是Internet的
网络层就相当于快递公司庞大的快递网络,全国不同的集散中心,比如说,从深圳发往北京的顺丰快递(陆运为例啊,空运好像直接就飞到北京了),首先要到顺丰的深圳集散中心,从深圳集散中心再送到武汉集散中心,从武汉集散中心再寄到北京顺义集散中心。这个每个集散中心,就相当于网络中的一个IP节点。

数据链路

将比特组合成字节,再将字节组合成帧,使用链路层地址 (以太网使用MAC地址)来访问介质,并进行差错
数据链路层又分为2个子层:逻辑链路控制子层(LLC)和媒体访问控制子层(MAC子层处理CSMA/CD算法、数据出错校验、成帧等;LLC子层定义了一些字段使上次协议能共享数据链路层。 在实际使用中,LLC子层并非必需的。

物理层

实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输快递寄送过程中的交通工具,就相当于我们的物理层,例如汽车,火车,飞机,船。

TCP/IP 五层模型

Python网络编程概述_第2张图片

网络编程开始之 网络基础

问题1? 网络上一个程序如何精准的找到另一个程序?

首先程序必须先启动,其次必须要有这台机器的地址,以及要连接的应用程序的主机的地址.而在计算机的应用程序中我们可以通过ip地址来标识台主机的地址,而如何确定是哪一个应用程序呢?这个时候就要引入一个端口号的概念,所谓端口号,就是用于区分一台计算机中不同应用程序的标识。

IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),
是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,
它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。
IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。
例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

总结:通过IP地址我们可以找到通信的是哪一个主机,而通过端口号,我们可以找到具体的主机上的是哪一个应用程序。网络中标识一个进程的方式:IP + 传输层协议 + 端口号

问题2? 什么是socket?

socket层

Python网络编程概述_第3张图片

描述

socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

其实站在你的角度上看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。
也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。

TCP/UDP

TCP(Transmission Control Protocol 传输控制协议) 可靠的,面向连接的协议(eg:打电话),传输效率低但是是全双工一对一的,面向字节流的协议.使用TCP的应用:Web浏览器,电子邮件,文件传输程序.

UDP(User Datagram Protocal 用户数据报协议)不可靠的,非面向连接的协议,传输效率高,可以一对一,一对多,多对一,多对多,面向报文的协议.使用UDP的应用:域名系统(DNS),视频流,IP语音

TCP/UDP的编程流程

Python网络编程概述_第4张图片

套接字(socket的使用)

基于TCP协议的socket

server端

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/22 10:34'
import socket

# 1.创建套接字,默认是TCP
sk = socket.socket()
# 解决端口一直被占用的情况
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 2.绑定地址
sk.bind(("127.0.0.1",9999))
# 3.设置监听
sk.listen()
# 4.等待连接
conn,addr = sk.accept()
# 5.连接成功,接收数据
ret = conn.recv(4096)
print(ret) # 带你
# 6.发送数据
conn.send(b'Receive Successful!')

# 7关闭套接字连接
conn.close()  # 关闭和客户端之间连接的套接字
sk.close() # 关闭服务器套接字

客户端

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/22 10:39'
import socket

# 创建套接字
sk = socket.socket()
# 建立连接
sk.connect(("127.0.0.1", 9999))
# 发送数据
sk.send(b'123')
# 接收响应数据
ret = sk.recv(4096)
print(ret)
# 关闭连接
sk.close()

基于UDP的socket

服务端

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/22 10:45'
import socket

# 1.创建一个UDP服务器的套接字,默认是TCP的,所以要传递参数type
sk = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)

# 2.绑定地址
sk.bind(("127.0.0.1", 8888))
# 3.接收消息
msg, addr = sk.recvfrom(4096)
# 4.发送消息
sk.sendto(b'123', addr)
# 5.关闭服务器套接字
sk.close()

客户端

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/22 10:52'
import socket

# 1.创建socket
sk = socket.socket(type=socket.SOCK_DGRAM)
# 2.发送数据
sk.sendto(b'hello', ('127.0.0.1', 8888))
# 3.接收响应数据
msg, addr = ret = sk.recvfrom(1024)
print(msg.decode('utf-8'), addr)
# 4.关闭连接
sk.close()

TCP协议的粘包

粘包是什么

TCP粘包产生的原因大体上可以分为两方面:
发送端:

发送端要等待缓冲区满才发送出去,造成粘包

接收

接收方不及时接收缓冲区的包,造成多个包接收.

TCP粘包主要从以下几个方面去分析:
1. 发送端: TCP连接是面向流的,使用了Nagle算法进行数据的发送优化
2. 接收端:TCP接收端,接收端的从缓冲区取出数据,取出的数据可以是发送端的多个包的组合.

TCP发送端的Nagle算法

TCP是面向连接的,所以TCP的socket编程,需要收发两端(客户端和服务器)都要有成对的socket,因此发送端
为了将多个发送接收端的包,更有效的发送给对方,使用了优化算法(Nagle算法),将多次间隔较小,数量较小的数据,合并成一个大的数据段,进行封包,这样接收端就不难于分辨出来了.因为是流式的字节流数据,没有消息边界.
这是发送端所产生的粘包.

保护消息边界和流

  • 什么是保护消息边界?

保护消息边界,就是指传输协议把数据当做一条独立的消息在网上传输,接收端只能接收独立的消息.也就是说存在保护消息边界,接收端一次只能接收发送端的发出的一个数据包.而TCP是面向流的传输,所以是没有保护消息边界的,如果发送端连续发送数据,接收端可能在一次接收中,接收了多个数据包,这样就可以能因为区分不了数据包的边界,而造成粘包.

而UDP之所以不会产生粘包,就是因为UDP是面向数据包传输的,它是由消息边界的.UDP的每一个消息都是独立的.UDP,由于是面向消息传输,它把所有接收到的消息都挂接到缓冲区的接收队列中,因此,它对于数据的提取分离更加的方便.UDP的发送和接收保证了,只要发送一次就会接收一次的原理,即使将多个包发送到缓存区,在接收区,也不会一次取出来,也是要经过相应次数的接收才能将数据取出来.

总结:粘包出现的原因

简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows网络编程)

1发送端需要等缓冲区满才发送出去,造成粘包

2接收方不及时接收缓冲区的包,造成多个包接收

具体点:

(1)发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

(2)接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。

粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。

不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。

在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘包问题时,分包算法就比较复杂。特别是粘在一起的包有不完整的包的粘包情况,由于一包数据内容被分在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。

避免粘包的措施

  1. 对于发送方引起的粘包现象,用户可以通过编程设置来避免,TCP提供了数据立即传输,而不使用优化到缓冲区的方法push.
    2)对于接受方引起的粘包,则可以通过程序优化程序设计,提高进程接收优先级,使其及时接收数据,避免产生粘包.

TCP无消息边界的解决方法

1. 发送固定长度的消息.比如我们发送的时候,可以规定我们消息的长度,这样接收端就知道要接收多少数据了
2.把消息的尺寸与消息一块发送
3.使用特殊的标识符来区分消息的间隔,注意这里这个间隔符不能出现在要发送的数据中.

HTTP协议详解

HTTP协议详解

问题1? HTTP和HTTPS的区别?

首先要回答这个问题,就必须知道有HTTP协议为什么还需要HTTPS协议?
超文本传输协议HTTP协议是用于web浏览器和服务器之间传递信息的,但是它在信息的传递
的过程中是明文的,不提供任何形式的数据加密.如果攻击者拦截到了Web浏览器和服务器之间的报文,就可以直接读取其中的内容.因此,HTTP协议不适合传输一些敏感的信息.例如银行卡卡号,账号密码等支付信息.

so,为了解决HTTP明文传送不安全的弊端,就推出了HTTPS这个协议.具体来说这个协议就是在HTTP协议的基础上添加了SSL协议,这个协议可以对浏览器和服务器之间传输的报文进行加密,以及通过证书对服务器进行验证.

HTTPS: 其实就是以安全为目标的HTTP通道,简单的说就是HTTP的安全版.它使用安全套接字层(SSL secure sockets layer)进行信息交换,简单的说它是HTTP的安全版.

总结 HTTP和HTTPS的区别?

  1. HTTP是明文传输文本的协议,而HTTPS是通过SSL安全套接字层进行加密之后的协议.
    2.HTTPS协议需要加入ca申请证书,一般免费证书很少,需要交费.
    3.HTTPS比HTTP多了两个东西,一个是SSL加密,保证数据传输的安全性.另一个就是信任证书,确定服务器的来源是安全的.
    4.HTTPS和HTTP连接的时候使用的端口号是不一样的,HTTPS默认是80端口,而后者是443.

问题2?简述HTTP的一次全过程

HTTP请求的整个流程
上个图先


Python网络编程概述_第5张图片

1. 第一步DNS域名解析

通过域名解析,获取到要连接的服务器的网路地址.

2. 建立TCP连接

三次握手,建立HTTP协议需要的支撑协议的TCP连接的三次握手.

3. 发起HTTP请求
浏览器发送报文,包括请求行,请求头,请求体以空行结束,向服务器发送报文.

4. 服务器收到报文,并根据请求的内容作出响应.

5. 浏览器收到报文,根据报文的文件类型,进行相应,解析和显示

注意HTTP1.0版本模式是短连接的,而HTTP1.1版本加入了长连接.如果浏览器或者服务器在其头部加入了这行代码:Connection:keep-alive

问题3?HTTP的长连接和短连接

什么是长连接和短连接?

短连接:

浏览器和服务器每进行一次HTTP操作(请求和响应),就建立一次连接,任务结束就中断连接.举个例子,比如浏览器访问一个HTML页面,包含有其他的web资源,例如js文件,图片,css文件等,每遇到一个web资源,就会建立一个HTTP连接.在HTTP1.0中,采用的都是短连接

长连接:

从HTTP1.1中,默认采用的是长连接,通过在报文的头部添加Connection:keep-alive来实现.当使用长连接的时候,客户端和服务器之间建立的TCP的连接通道不会关闭,如果浏览器再请求这个服务器上的资源,可以使用这个连接.长连接也不是无限期的连接,它有一个保持时间,可以在服务器软件中设定这个时间.

注意: HTTP的长连接和短连接,实际上是TCP的长短连接,并且必须浏览器和服务器同时都支持才可以

长连接和短连接的优缺点

  1. 长连接可以减少频繁的创建和关闭连接,一定程度上节约了时间,减少浪费.对于请求和响应比较频繁的操作来说,使用长连接比较合适.但是长连接存在一个问题,因为一直维持着连接,如果服务器上连接的浏览器用户较多的时候,对服务器的负载来说是各考验.这个时候服务器就要采取一些策略,比如关闭一些长时间没有进行操作的连接.

2.短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段.但是如果客户端请求比较频繁,将会在TCP建立连接和关闭连接上浪费时间和宽带.

什么时候使用长连接和短连接
长连接多用于操作频繁,点对点的通信,而且连接数不能太多的情况.
而短连接适用于那些连接不是很频繁,但是连接人数比较多的情况.

你可能感兴趣的:(Python网络编程概述)