微前端架构如何改变企业的开发模式与效率提升
1090
2022-10-06
Python网络编程之网络基础
Python网络编程之网络基础
一、前言二、为什么要使用通信协议三、TCP/IP简介
1.IP协议2.TCP协议
四、UDP简介五、Socket 简介
一、前言
计算机网络就是把各个计算机连接到一起,让网络中的计算机可以相互通信。网络编程就是如何在程序中实现两台计算机的通信。本文将讲解网络的基础知识,包括比较常见的TCP协议和UDP协议,以及如何使用TCP编程和UDP编程。
当今的时代是一个网络的时代,网络无处不在。而我们前面学习编程的程序都是单机的,即不能和其他电脑上的程序进行通信。为了实现不同电脑之间的通信,就需要使用网络编程。下面我们来了解一下网络相关的基础知识。
二、为什么要使用通信协议
计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM、Apple和Microsoft都有各自的网络协议,互不兼容,这就好比一群人说英语,有的说中文,有的说德语,说同一种语言的人可以交流,不同的语言之间就不行了,如图所示:
为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为了实现互联网这个目标,互联网协议簇(Internet Protocol Suite)即通用协议标准出现了。Internet是由inter和net两个单词组合起来的,愿意就是连接“网络”的网络,有了Internet,任何私有网络,只要支持这个协议,就可以接入互联网。
三、TCP/IP简介
因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网协议简称TCP/IP协议。
1.IP协议
在通信时,通信双方必须知道对方标识,好比发送快递必须知道对方的地址。互联网上每个计算机的唯一标识就是IP地址。IP地址实际上是一个32位整数(称为IPv4),它是以字符串表示的IP地址,如172.16.254.1,实际上是把32位整数按8位分组后的数字表示,目的是便于阅读,如图所示:
IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,类似于将一个大包裹拆分成几个小包裹,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由。但是不保证都能到达,也不能保障顺序到达。
2.TCP协议
TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议通过三次握手建立可靠连接,如图所示:
然后需要对每个IP包进行编号,确保对方按顺序收到,如果包丢了,就自动重发。如图所示:
许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址、源端口和目标端口。
端口有什么作用?在两台计算机通信时,只要发送IP地址是不够的,因为同一台计算机上运行着多个网络程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。
一个进程也可能同时与多个计算机建立连接,因此它会申请很多端口,端口号不是随意使用的,而是按照一定的规则进行分配。例如,80端口分配给HTTP服务,21端口分配给FTP服务。
四、UDP简介
相对TCP协议,UDP协议则是面向无连接的协议。使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,数据无法保障一定到达。虽然用UDP传输数据不可靠,但它的优点是比TCP协议的速度快。对于不要求可靠到达的数据而言,就可以使用UDP协议。TCP协议和UDP协议的区别如图所示:
五、Socket 简介
为了让两个程序通过网络进行通信,二者均必须使用 Socket 套接字。Socket 的英文原义是“孔”或“插座”,通常也称为“套接字”,用于描述IP和端口,它是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信,如图所示,在Internet上的主机上一般运行了多个服务软件,同时提供几种服务,每种服务打开一个Socket,并绑定到一个端口上,不同的端口对应不同的服务。
Socket 正如其英文原义那样,像多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。
在Python中使用socket模块的socket()函数就可以完成,语法格式如下:
s = socket.socket(AddressFamily, Type)
函数socket.socket创建一个socket,返回该socket的描述符,该函数带有两个参数:
AddressFamily:可以选择AF_INET(用于Internet进程间通信)或者AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET。Type:套接字类型,可以是SOCK_STREAM(流式套接字,主要用于TCP协议)或者SOCK_DGRAM(数据报套接字,主要用于UDP协议)。
例如,为了创建TCP/IP套接字,可以用下面的方式调用socket.socket():
tcpSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
同样,为了创建UDP/IP套接字,需要执行以下语句:
udpSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
创建完成后,生成一个socket对象,socket对象的主要方法如下表所示:
socket 对象的内置函数
函数 | 功能 |
服务器端套接字函数 | |
bind() | 用于绑定地址(host, port)到套接字,在 AF_INET 下,以元组(host, port)的形式表示地址 |
listen() | 用于开始 TCP 监听。backlog 指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 即可 |
accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字函数 | |
connect() | 主动初始化 TCP 服务器连接,一般 address 是形式为(hostname, port)的二元组,如果连接出错,则返回socket.error错误 |
connect_ex() | connect() 函数的扩展版本,在出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数 | |
recv() | 接收 TCP 数据,数:据以字符串形式返回,bufsize 指定要接收的最大数据量,flags 提供有关消息的其他信息,通常可以忽略 |
send() | 发送 TCP 数据,将字符串中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于字符串的长度 |
sendall() | 完整发送 TCP 数据。将字符串中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。若成功,则返回 None;若失败,则抛出异常 |
recvform() | 接收 UDP 数据,与 recv() 的功能类似,但返回值是 (data, address)。其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址 |
公共用途的套接字函数 | |
sendto() | 发送 UDP 数据,将数据发送到套接字,address 是形式为 (ipaddr, port) 的元组,用于指定远程地址。返回值是发送的字节数 |
close() | 关闭套接字 |
getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr, port) |
getsockname() | 返回套接字自己的地址。返回值通常是元组(ipaddr, port) |
setsockopt(level, optname, value) | 设置给定套接字选项的值 |
getsockopt(level, optname[,buflen]) | 返回套接字选项的值 |
settimeout(timeout) | 设置套接字操作的超时时间,timeout 是一个浮点数,单位是秒。值为 None 表示没有超时时间。一般,超时时间应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
gettimeout() | 返回当前超时时间的值,单位是秒,如果没有设置超时时间,则返回 None |
fileno() | 返回套接字的文件描述符 |
setblocking(flag) | 如果 flag 为 0,则将套接字设为非阻塞模式;否则,将套接字设为阻塞模式(默认值)。在非阻塞模式下,如果调用 recv() 没有发现任何数据,或 send() 调用无法立即发送数据,那么将引起 socket.error 异常 |
makefile() | 创建一个与套接字相关联的文件 |
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~