网络编程
1. 引子
假如有俩脚本,foo.py,
bar.py,分别运行,都可以正常运行,但是现在想从两个程序间传递一个数据。
- 同一台电脑
- 创建一个文件,将foo.py的数据读入文件中,bar.py从文件中读取数据
- 不同电脑间
- 该如何做
软件佛如开发架构
C/S架构
C/S 即使Client和Server----->客户端和服务器端架构
B/S架构
B/S即Browser和Server ---->浏览器和服务器端架构
什么是网络
网络就是一种辅助双方或者多方能够连接在一起的工具
伴随着网络发展,人们使用了很多通信方法,有些已不再使用,现在使用最广泛的是TCP/IP (Transmission Control Protocal/Internet Protocal)
TCPMP是标准的协议,其可以使世界范围内的计算机通过Internet或本地网络通信
TCP/IP事实上是一些协议(protocols)的合集。当前大多数使用中的通信都使用TCP协议。
Internet是在一些共享的线路上发送数据’的。例如:在您的计算机上也许同时运行着几个应用程序,如Web浏览器、通讯软件等程序,而您只须通过一条单一的线路来连接互联网。上面所有的程序都共享这个连接,简单地说,用户往往不会觉察到这个共享的发生。
目的
- 使用网络把多方连接在一起,然后,进行数据传输
- 为了让不同电脑的软件可以互相传递,借助网络的功能
网络编程的定义
让不同电脑中的软件进行数据传递,即网络中不同主机进程间的通信
地址
1. 生活中的地址与标识
不同的网络中,采用唯一的标识来区分不同的主体,比如车牌号、建筑物地址、电话号码、员工编号等等
一台电脑怎么找到很多电脑中的一台呢?
警察怎么找到嫌疑犯的?
2. ip地址的作用
ip地址:用来在网络中标记一台电脑,比如192.168.1.1;在同一网络中是唯一的。
同一网络:好比班级编号,球队编号。
同一网络:例如同一个局域网, 一个教室里。
3.IP地址分类
目前ip主要分为两种
- ipV4,32位二进制构成 分成四段,每段范围0-255(2的八次方,四个字节)
- ipV6,128位二进制构成 分成八段,每段范围0-16的四次方
每一个IP包含两部分:
- 网络号
- 主机号
类似电话号由区号
二进制 | 八进制 | 十进制 | 十六进制 |
---|---|---|---|
0000 0001 | 0000 0001 | 1 | 0000 0001 |
0000 0010 | 0000 0002 | 2 | 0000 0002 |
0000 0011 | 0000 0003 | 3 | 0000 0003 |
0000 0100 | 0000 0004 | 4 | 0000 0004 |
进制基数为base
各进制到十进制的进化
\sum_{i=1}^{n}*
开放式系统互联参考模型(Open System Interconnection Reference Model)–>简称OSI
这个标准定义了网络的七层框架,试图使得计算机在整个世界范围内实现互联。
在OSI中,网络体系结构被分成下面的七层。
- 物理层
- 定义了通信设备的传输规范,规定了激活、维持和关闭通信节点之间的机械特性、电气特性和功能特性等。此层为上层协议提供了一个传输数据的物理媒介。
- 数据链路层
- 定义了数据封装以及传送的方式。这个层次的数据单位称为“帧”。数据链路层包括两个重要的子层:逻辑链路控制层(Logic Link Control,LLC)和介质访问控制层(Media Access Control,MAC)。LLC用来对节点间的通信链路进行初始化,并防止链路中断,确保系统的可靠通信。而MAC则用来检测包含在数据帧中的地址信息。这里的地址是链路地址或物理地址,是在设备制造的时候设置的。网络上的两种设备不能有相同的物理地址,否则会造成网络信息传送失败。
- 网络层
- 定义了数据的寻址和路由方式。这一层负责对子网间的数据选择路由,并实现网络互连等功能。
- 传输层
- 为数据提供端到端传输。这是比网络层更高的层次,是主机到主机的层次。传输层将对上层的数据进行分段并进行端到端传输。另外,还提供差错控制和流量控制机制。
- 会话层
- 用来为通信的双方制定通信方式,包括建立和拆除会话。另外,此层将会在数据中插入校验点来实现数据同步。
- 表示层
- 为不同的用户提供数据和信息的转换。同时还提供解压缩和加解密服务。这一层保证了两个主机的信息可以互相理解。
- 应用层
- 控制着用户绝大多数对于网络应用程序的访问,提供了访问网络服务的接口。
[外链图片转存失败(img-ppp1TGmv-1565007842112)(D:\正式学习python\picture\TIM图片20190805102703.jpg)]
端口查看:
netstat -ano
Socket简介
不同的电脑上进程的标识与识别
用唯一标识来标记一个进程
在电脑上,可以通过用进程号(PID)来唯一标识进程。但是在网络上,不可以。需要利用TCP/IP协议来帮我们解决问题
- 用IP可以唯一标识网络中的主机,协议+端口号唯一标识主机中的应用进程。
进程指的是,运行程序以及运行程序用到的资源的整体就称之为进程
什么是Socket
socket是进程间通信的一种方式
与其他进程通信的一个主要不同的是:
它能实现不同主机间的进程间的通信
先行大多数服务都是基于Sockt来完成通信的
比如 浏览网页,QQ聊天,收发email
创建一个socket
import socket
socket.socket(AddressFamily,Type)
参数说明:
-
AddressFamily
- AF_INET,Internet间进程间通信(实际工作最常用)
- AF_UNIX,同一台机器进程间通信
-
Type 套接字类型
- SOCK_DGRAN,数据报套接字,主要用于UDP协议
- SOCK_STREAM,流式套接字,主要用于TCP协议
-
简单的实例
-
客户端client
-
import socket #创建一个socket对象 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #获取本地主机名 host = socket.gethostname() #设置端口号 port=9996 #连接服务,指定主机和端口 s.connect((host,port)) #接收小于1024字节的数据 msg=s.recv(1024) s.close() print(msg.decode('utf-8'))
-
-
服务端
-
import socket #创建一个socket对象 serversocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #主机名 host=socket.gethostname() #端口号 port=9996 #绑定端口 serversocket.bind((host,port)) #设置最大连接数,超过后排队 serversocket.listen(5) while True: #建立客户端连接 clientsocket,addr=serversocket.accept() print("链接地址:\t %s"%(str(addr))) msg='网络变成测试'+'\r\n' clientsocket.send(msg.encode('utf-8')) clientsocket.close()
-
UDP网络程序
UDP -->User Datagram Protocol(用户数据报协议)是一个无连接的简单的面向数据报的运输层协议。
优缺点:
- 优点
传输速度快(UDP在传输时无需在客户端和服务器端之间建立连接,也无超时重新发送机制)
-
缺点
不能保证可靠性(UDP是一种面向无连接的协议,每个数据都是一个独立的信息,包含完整的源地址或者目的地址,在网络上以任何可能的路径传往目的地址,在网络上以任何可能的路径传往目的地。因此,能够到达目的地,以及到达目的地的时间和内容的正确性都无法保证)
-
特点
- UDP是面向无连接的通讯协议
- UDP包括目的的端口号和源端口号信息,通讯不需要连接,能够实现广播发送
- UDP数据大小有限制,每个被传输的数据报必须限定64K以内
- UDP是一个不可靠的协议,发送出去的数据不一定以相同次序到达接收方
- UDP一般多用于多点通信和实时的数据业务。比如:
- 视频
- 语音广播等
发送数据
创建一个UDP客户端程序的流程:
- 创建一个客户端套接字
- 发送/接收数据
- 关闭套接字
socket和file的区别
- file针对指定模块进行打开,读写,关闭
- socket针对服务端和客户端socket进行打开,读写,关闭
[外链图片转存失败(img-xeoKn6Tr-1565007842116)(C:\Users\xdw\AppData\Roaming\Typora\typora-user-images\1564989440461.png)]
发送数据
import socket
while True:
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr=('192.168.1.120',8234)
sendData=input("请输入发送的数据:")
udp_socket.sendto(sendData.encode('gbk'),addr)
udp_socket.close()
接收返回值
import socket
udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
Addr=('192.168.1.112',8345)
sendData= input('请输入要发送的数据:')
udp_socket.sendto(sendData.encode('utf-8'),Addr)
receive_data=udp_socket.recvfrom(1024)
print(receive_data)
udp_socket.close()
Socket 对象(内建)方法
函数 | 描述 |
---|---|
服务器端套接字 | |
s.bind() | 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字 | |
s.connect() | 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
s.connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数 | |
s.recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
s.sendall() | 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvform() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字 |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 |
s.makefile() | 创建一个与该套接字相关连的文件 |
用网络调试助手时,端口号会一直变动
UDP端口号绑定
2. udp绑定端口
2.1 绑定端口
一般情况下,在一台电脑上运行的网络程序有很多,为了不与其他的网络程序占用同一个端口号,往往在编程中,udp的端口号一般不绑定
但是如果需要做成一个服务器端的程序的话,是需要绑定的,想想看这又是为什么呢?
如果报警电话每天都在变,想必世界就会乱了,所以一般服务性的程序,往往需要一个固定的端口号,这就是所谓的端口绑定
Demo:
总结
- 一个UDP网络程序可以不绑定端口,此时会自动分配一个端口。重新运行此程序,端口号可能会发生变化
- 一个UDP网络程序,可以绑定信息(IP,Ports),如果绑定成功,那么操作系统用这个端口号来进行区别收到的网络数据是否是此进程的。
TCP简介
TCP协议,传输控制协议(Transmission Coutrol Protocol),是一种面向连接的,可靠的,基于字节流的传输层通信协议。
TCP通信需要经过i创建连接,数据传输,终止连接三个步骤。
TCP特点
面向连接
通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。
双方间的数据传输都可以通过这个连接进行。
完成数据交换后,双方断开此连接,以释放系统资源。
这种连接是一对一的
因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。
可靠传输
1)TCP采用发送应答机制
TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功
2)超时重传
发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。
TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。
3)错误校验
TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
- 流量控制和阻塞管理
流量控制用来避免主机发送得过快而使接收方来不及完全收下。
TCP和UDP的不同点
- 面向连接
- 有序的数据传输
- 无差错的数据传输(重发丢失的数据包,舍弃重复的数据包)
- 阻塞/流量控制
- TCP通信模型,类似‘打电话’,先通信开始前一定要建立相关连接,才能发送数据;而UDP通信模型,类似’写信,不需要建立相关连接,发送数据即可‘
号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。
3)错误校验
TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
- 流量控制和阻塞管理
流量控制用来避免主机发送得过快而使接收方来不及完全收下。
TCP和UDP的不同点
- 面向连接
- 有序的数据传输
- 无差错的数据传输(重发丢失的数据包,舍弃重复的数据包)
- 阻塞/流量控制
- TCP通信模型,类似‘打电话’,先通信开始前一定要建立相关连接,才能发送数据;而UDP通信模型,类似’写信,不需要建立相关连接,发送数据即可‘
[外链图片转存失败(img-Vm7gcQ9f-1565007842117)(C:\Users\xdw\AppData\Roaming\Typora\typora-user-images\1564997267850.png)]