网络编程入门
计算机网络基础
计算机网络是独立自主的计算机互联而成的系统的总称,组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享。
计算机网络发展史
- 1960s - 美国国防部ARPANET项目问世,奠定了分组交换网络的基础。
- 1980s - 国际标准化组织(ISO)发布OSI/RM,奠定了网络技术标准化的基础。
- 1990s - 英国人蒂姆-博纳斯-李发明了图形化的浏览器,浏览器的简单易用性使得计算机网络迅速被普及。
有无浏览器,计算机使用的区别:
TCP/IP模型
实现网络通信的基础是网络通信协议,这些协议通常是由互联网工程任务组 (IETF)制定的。所谓"协议"就是通信计算机双方必须共同遵从的一组约定,例如怎样建立连接、怎样互相识别等。
网络协议的三要素是:语法、语义和时序。
构成我们今天使用的 Internet 的基础的是 TCP/IP 协议族,所谓协议族就是一系列的协议及其构成的通信模型,我们通常也把这套东西称为 TCP/IP 模型。TCP/IP 是一个四层模型,也就是说,该模型将我们使用的网络从逻辑上分解为四个层次,自底向上依次是:网络接口层、网络层、传输层和应用层。
IP 通常被翻译为网际协议,它服务于网络层,主要实现了寻址和路由的功能。接入网络的每一台主机都需要有自己的IP地址,IP地址就是主机在计算机网络上的身份标识。
当然由于IPv4地址的匮乏,我们平常在家里、办公室以及其他可以接入网络的公共区域上网时获得的IP地址并不是全球唯一的IP地址,而是一个局域网(LAN)中的内部IP地址,通过网络地址转换(NAT)服务我们也可以实现对网络的访问。
计算机网络上有大量的被我们称为"路由器"的网络中继设备,它们会存储转发我们发送到网络上的数据分组,让从源头发出的数据最终能够找到传送到目的地通路,这项功能就是所谓的路由。
TCP全称传输控制协议,它是基于IP提供的寻址和路由服务而建立起来的负责实现端到端可靠传输的协议,之所以将TCP称为可靠的传输协议是因为TCP向调用者承诺了三件事情:
- 数据不传丢不传错(利用握手、校验和重传机制可以实现)。
- 流量控制(通过滑动窗口匹配数据发送者和接收者之间的传输速度)。
- 拥塞控制(通过RTT时间以及对滑动窗口的控制缓解网络拥堵)。
网络应用模式
- C/S 模式和 B/S 模式。这里的 C 指的是 Client(客户端),通常是一个需要安装到某个宿主操作系统上的应用程序;而 B 指的是 Browser(浏览器),它几乎是所有图形化操作系统都默认安装了的一个应用软件;通过 C 或 B 都可以实现对 S(服务器)的访问。
- 去中心化的网络应用模式。不管是 B/S 还是 C/S 都需要服务器的存在,服务器就是整个应用模式的中心,而去中心化的网络应用通常没有固定的服务器或者固定的客户端,所有应用的使用者既可以作为资源的提供者也可以作为资源的访问者。
基于HTTP协议的网络资源访问
HTTP(超文本传输协议)
HTTP 是超文本传输协议(Hyper-Text Transfer Proctol)的简称。超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议,它是万维网数据通信的基础,设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法,通过 HTTP 或者 HTTPS (超文本传输安全协议)请求的资源由 URI(统一资源标识符)来标识。
简单的说,通过 HTTP 我们可以获取网络上的(基于字符的)资源,开发中经常会用到的网络 API(有的地方也称之为网络数据接口)就是基于 HTTP 来实现数据传输的。
JSON格式
JSON(JavaScript Object Notation)是一种轻量级的数据交换语言,该语言以易于让人阅读的文字(纯文本)为基础,用来传输由属性值或者序列性的值组成的数据对象。尽管 JSON 是最初只是 Javascript 中一种创建对象的字面量语法,但它在当下更是一种独立于语言的数据格式,很多编程语言都支持 JSON 格式数据的生成和解析,Python 内置的 json 模块也提供了这方面的功能。由于 JSON 是纯文本,它和 XML 一样都适用于异构系统之间的数据交换,而相较于 XML ,JSON 显得更加的轻便和优雅。
XML:
XML
<?xml version="1.0" encoding="UTF-8"?>
<message>
<from>xiaoming</from>
<to>xiaohong</to>
<content>do you want to make friends with me ?</content>
</message>
JSON:
javascript
{
"from": "xiaoming",
"to": "xiaohong",
"content": "do you want to make friends with me ?"
}
requests库
requests 是一个基于 HTTP 协议来使用网络的第三库。
简单的说,使用 requests 库可以非常方便的使用 HTTP ,避免安全缺陷、冗余代码以及"已有的或是早已被优化過的基本方法。
通过 requests 来实现一个访问网络数据接口并从中获取图片下载链接然后下载图片到本地 。
python
from time import time
from threading import Thread
import requests
# 继承Thread类创建自定义的线程类
class DownloadHanlder(Thread):
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
filename = self.url[self.url.rfind('/') + 1:]
resp = requests.get(self.url)
with open('/Users/tp/' + filename, 'wb') as f:
f.write(resp.content)
def main():
# 通过requests模块的get函数获取网络资源
# 下面的代码中使用了天行数据接口提供的网络API
# 要使用该数据接口需要在天行数据的网站上注册
# 然后用自己的Key替换掉下面代码的中APIKey即可
resp = requests.get(
'http://api.tianapi.com/meinv/?key=APIKey&num=10')
# 将服务器返回的JSON格式的数据解析为字典
data_model = resp.json()
for mm_dict in data_model['newslist']:
url = mm_dict['picUrl']
# 通过多线程的方式实现图片下载
DownloadHanlder(url).start()
if __name__ == '__main__':
main()
基于传输层协议的套接字编程
套接字这个词对很多不了解网络编程的人来说显得非常晦涩和陌生,其实说得通俗点,套接字就是一套用 C 语言写成的应用程序开发库,主要用于实现进程间通信和网络编程,在网络应用开发中被广泛使用。
在 Python 中也可以基于套接字来使用传输层提供的传输服务,并基于此开发自己的网络应用。
实际开发中使用的套接字可以分为三类:流套接字(TCP 套接字)、数据报套接字和原始套接字 。
TCP套接字
所谓 TCP 套接字就是使用 TCP 协议提供的传输服务来实现网络通信的编程接口。在 Python 中可以通过创建 socket 对象并指定 type 属性为 SOCK_STREAM 来使用 TCP 套接字。由于一台主机可能拥有多个 IP 地址,而且很有可能会配置多个不同的服务,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的 IP 地址和端口上。这里的端口并不是物理设备而是对 IP 地址的扩展,用于区分不同的服务,例如我们通常将 HTTP 服务跟 80 端口绑定,而 MySQL 数据库服务默认绑定在 3306 端口,这样当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是 HTTP 服务器还是数据库服务器提供的服务。端口的取值范围是 0~65535 ,而 1024 以下的端口我们通常称之为"著名端口"(留给像 FTP、HTTP、SMTP 等"著名服务"使用的端口,有的地方也称之为"周知端口"),自定义的服务通常不使用这些端口,除非自定义的是 HTTP 或 FTP 这样的著名服务。
UDP套接字
传输层除了有可靠的传输协议 TCP 之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称 UDP 。TCP 和 UDP 都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了 TCP 中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP 可能是更好的选择。可能大家会注意到一个现象,就是在观看网络视频时,有时会出现卡顿,有时会出现花屏,这无非就是部分数据传丢或传错造成的。在 Python 中也可以使用 UDP 套接字来创建网络应用。