通过python的网络通信支持,通过网络模块,python程序可以非常方便地相互访问互联网上的HTTP服务和FTP服务等。可以直接获取互联网上的远程资源,还可以向远程资源发送GET POST请求。
(一)了解计算机网络的基础知识
计算机网络是线代通信技术与计算机技术相结合的产物,计算机网络主要可以提供
- 资源共享
- 信息传输与集中处理
- 均衡负荷与分布处理
- 综合信息服务
按照规模大小和延伸范围可以分为:广域网(WAN),城域网(MAN),局域网(LAN)
计算机网络中实现通信必须有一些约定,这些约定被称为通信协议。通信协议负责传输速率,传输代码,代码结构,传输控制步骤、出错控制等标准。
通信协议一般由三部分组成:一是语义部分,用于决定双方对话类型;二是语法部分,用于决定双方对话的格式;三是变化规则,用于决定通信双方的应答关系。
OSI 参考模型把计算机划分为:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层七层。
应用层:与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。有HTTP, FTP , NFS, SMTP, TELNET
表示层:这一层主要是定义数据格式及加密。如加密, ASCII
会话层:它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的。如 RPC,SQL
传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在泳衣主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能,如 TCP UDP SPX
网络层:这层对端对端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。如IP
数据链路层:它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关
物理层:OSI的物理层规范是有关传输介质的特性,这些规范通常也参考了其他组织制定的标准。
image.png
IP地址用于唯一标识网络中的一个通信实体,这个通信实体既可以是一个主机,也可以是路由器的某个端口,。而在基于IP协议的网络中传输数据包都必须使用IP地址来进行标识。
端口,程序与外界进行交互的出入口。
公认端口: 0 ~ 1023绑定了一些特定的服务
注册端口 : 1024 ~ 49151 绑定一些业务
私有端口 : 49152 ~ 65535 应用程序动态的端口使用
image.png
Python标准库中的网络模块
(二)基于TCP协议的网络编程
Tcp/IP通信协议是一种可靠的网络协议,他在通信的两端建立一个socket,从而形成虚拟的网络链路。一旦建立了虚拟网络链路,两端的程序就可以通过该链路进行通信。
TCP 协议基础
IP 是Internet上使用的一个关键协议,通过IP协议,使internet成为一个允许连接不同类型的计算机和不同操作系统的网络。同时还需要TCP协议来提供可靠且无差错的服务。
TCP协议被称为端对端协议,这是因为他在两台计算机的连接中起了非常重要的角色,当一台计算机需要与另外一台计算机连接时,TCP协议会让他们之间建立一个虚拟链路,用于发送和接受数据。
TCP协议负责收集这些数据包,并将其按照适当的顺序传送,接收端收到数据包后将其正确的还原。TCP保证数据包在传送过程中准确无误。TCP协议采用重发机制,当一个通信实体发送一个消息给另外一个通信实体后,需要接收到另外一个通信实体的确认信息,如果没有接收到该确认信息,则会重发信息。
image.png
使用socket创建TCP服务端
使用socket之前,必须先创建socket对象,可通过该类的构造器来创建socket实例。
socket.socket(family = AF_INET, type= SOCK_STREAM, proto=0, fileno= None)
family 参数用于指定网络的类型。
type 参数用于指定网络Sock类型。SOCK_STREAM(默认值,创建TCP协议的socket)
proto 参数用于指定协议号,如果没有特殊要求,一般为0
在创建socket后要将两个socket连接起来。作为服务端使用的socket必须绑定IP地址和端口,并在端口进行监听。
socket对象常用的方法:
socket.bind(address):将socket绑定到指定的address,指定的address可以是一个元组,包含IP 和端口
socket.accept() 作为服务端使用的socket调该方法接受来自客户端的连接。
socket.close()关闭连接
socket.recv(): 接收socket中的数据,该方法返回一个bytes对象代表接收到的数据
socket.send(bytes[, flags]) 向socket中发送数据,该socket必须与远程socket之间建立了连接。
socket.listen()服务端使用socket调用监听
基本步骤
-
服务端先创建一个socket对象
-
服务端socket将自己绑定到指定IP和端口
-
服务端socket调用自己的listen()方法
-
程序不断循环接收来自客户端的连接
#创建socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 将socket绑定到本机IP地址和端口
s.bind(('0.0.0.0', 8000))
#服务端开始监听来自客户端的连接
s.listen()
while True:
#每当接收到客户端请求时,就返回对应的socket和远程地址
c, addr = s.accept()
socket客户端
创建客户端的步骤:
-
客户端先创建一个socket对象
-
客户端socket调用connect() 方法连接远程服务器地址
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((('127.0.0.1', 8000)))
小实例:服务端
import socket
import threading
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8000))
server.listen()
def handle_sock(sock, addr):
while True:
data = sock.recv(1024)
print(data.decode("utf8"))
re_data = input()
sock.send(re_data.encode("utf8"))
while True:
sock, addr = server.accept()
'''用线程去处理新接收的连接(用户)'''
client_thread = threading.Thread(target=handle_sock, args=(sock, addr))#传的一定是函数名称
client_thread.start()
客户端:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
re_data = input()
client.send(re_data.encode("utf8"))
data = client.recv(1024)
print(data.decode("utf8"))
通过这样就可以实现socket之间的通信。