网络编程
一、软件开发架构
两个程序之间通讯的应用大致可以分为两种:
①、应用类程序。用户需要安装客户端才可使用的程序。
②、web类程序。用户只需要浏览器即可访问的程序。
1、客户端、服务端概念
客户端:就是我们常用的程序例如QQ、微信、浏览器等。
服务端:要一直运行,给他人提供服务的机器(电脑、服务器等)。
2、C/S架构
C/S架构即client与server架构,中文意思即客户端与服务器端架构。
3、B/S架构
B/S架构即browser与server架构,中文意思即浏览器端与服务器端架构。
二、计算机网络
mac:是网卡上的全球唯一的物理地址。
ip:每台电脑上都有一个全球唯一的标识,就是ip。通过ip地址能获得物理地址。
端口:电脑上的每个应用程序想运行,必须占用一个端口号。端口号同时间只能由一个应用程序占用。每台电脑有65536个端口。
局域网:local area network,简称LAN,是指在某一区域内由多台计算机互联组成的计算机组。
广域网:wide area network,简称WAN,是一种跨越大的,地域性的计算机网络的集合。
三、网络协议(TCP/IP协议族)
1、什么是网络协议
网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
2、什么是TCP/IP协议族
互联网有上百种协议,但是最重要的两个协议是TCP协议和IP协议,因此将上百种协议统称为TCP/IP协议族。
四、TCP协议
1、什么是TCP协议
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议
2、TCP协议的特点:
①、数据安全
②、速度略低
③、分为客户端和服务端
3、连接建立(3次握手)
TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。
TCP三次握手的过程如下:
①、客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
②、服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
③、客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
4、连接终止(4次挥手)
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。
①、某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
②、接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
③、一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
④、接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
五、UDP协议
1、什么是UDP协议
UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
2、UDP协议的特点
不可靠快速传输
六、TCP和UDP对比
TCP:提供的是面向连接,可靠的服务。在客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超市重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP:是一个简单的不可靠的运输层协议。它只是把应用程序传给IP层的数据报发送出去,但是并不能保证数据能到达目的地。由于UPD在传输数据报前不用在用户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
七、OSI/RM协议
1、什么是OSI/RM协议
OSI/RM协议是由ISO(国际标准化组织)制定的,它有三个基本的功能:提供给开发者一个必须的、通用的概念以便开发完善、可以用来解释连接不同系统的框架。
2、OSI将计算机网络体系结构(architecture)划分为以下七层:
应用层(Application Layer)。用户的应用程序和网络之间的接口,老板。
表示层(Presentation Layer)、协商数据交换格式 相当公司中简报老板、替老板写信的助理。
会话层(Session Layer)、允许用户使用简单易记的名称建立连接 相当于公司中收寄信、写信封与拆信封的秘书。
传输层(Transport Layer)、提供终端到终端的可靠连接 相当于公司中跑邮局的送信职员。
网络层(Network Layer)、使用权数据路由经过大型网络 相当于邮局中的排序工人。
数据链路层(Data Link Layer)、决定访问网络介质的方式。在此层将数据分帧,并处理流控制。本层指定拓扑结构并提供硬件寻址,相当于邮局中的装拆箱工人。
物理层(Physics Layer)、将数据转换为可通过物理介质传送的电子信号 相当于邮局中的搬运工人。
八、socket
1、什么是socket
Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
2、连接过程
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
①、服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
②、客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
③、接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
3、基于TCP协议的socket的使用
1、3次握手,4次挥手
①、服务端
from socket import *
server_socket = socket(AF_INET,SOCK_STREAM)
address = ("192.168.101.147",9999) #本地地址、端口号
server_socket.bind(address)#绑定本地地址,和端口号
server_socket.listen(5)#变主动为被动,监听最多5个连接
lianjie = server_socket.accept()#接受客户端发来的连接
while True:
data = lianjie[0].recv(128)
print(data.decode("utf_8"))
x = "我接到了:"+ data.decode("utf-8")
lianjie[0].send(x.encode("utf-8"))
②、客户端
import socket,threading
c_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
dest_address = ("192.168.101.147",9999) #远程地址
lock_address = ("192.168.101.147",8888) #本地地址
c_client.bind(lock_address)#绑定本地地址
c_client.connect(dest_address)#主动跟服务器连接
while True:
data = input("请输入数据:")
if data == "quit":
break
c_client.send(data.encode("utf-8"))
recv = c_client.recv(128)
print(recv.decode("utf-8"))
c_client.close()
用多线程写一个TCP
①、客户端
import socket, threading
def recv():
while True:
data = c_client.recv(128)
print(data.decode("utf-8"))
def send():
while True:
data = input("")
c_client.send(data.encode("utf-8"))
if __name__ == '__main__':
# 创建TCP Socket:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 服务器之间网络通信,数据流式socket ,for TCP
dest_address = ("192.168.101.147", 9999) # 远程地址
lock_address = ("192.168.101.147", 8888) # 本地地址
c_client.bind(lock_address) # 绑定本地地址
c_client.connect(dest_address) # 主动跟服务器连接
t1 = threading.Thread(target=recv)
t2 = threading.Thread(target=send)
t1.start()
t2.start()
②、服务端
import threading
from socket import *
def recv():
while True:
r = lianjie[0].recv(128)
print(r.decode("utf-8"))
def send():
while True:
data = input("")
lianjie[0].send(data.encode("utf-8"))
if __name__ == '__main__':
servers_sock = socket(AF_INET,SOCK_STREAM)
lock_address = ("192.168.101.147",9999) # 本地地址
servers_sock.bind(lock_address) # 绑定本地地址
servers_sock.listen(5)
lianjie = servers_sock.accept()
t1 = threading.Thread(target=recv)
t2 = threading.Thread(target=send)
t1.start()
t2.start()
4、基于UDP协议的socket的使用
import threading
import socket
def recv():
while True:
print(tc.recv(128).decode("utf-8"))
def send():
while True:
data = input("请输入数据:")
if data == "quit":
break
tc.sendto(data.encode("utf-8"), remote_address)
if __name__ == '__main__':
tc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
loc_address = ("192.168.101.147", 8888)
tc.bind(loc_address)
remote_address = ("192.168.101.179", 9999)
t1 = threading.Thread(target=send)
t2 = threading.Thread(target=recv)
t1.start()
t2.start()
九、urllib网络请求模块
1、什么是urllib网络请求模块
把url地址中指定的网络资源从网络流中读取出来,保存在本地。
2、使用urllib网络请求模块
urllib.request 模块提供了最基本的构造 HTTP 请求的方法,利用它可以模拟浏览器的一个请求发起过程.
同时它还带有处理 authenticaton (授权验证), redirections (重定向), cookies (浏览器Cookies)以及其它内容。
好,那么首先我们来感受一下它的强大之处,我们百度为例,我们来把这个网页抓下来。
3、爬取百度首页
from urllib import request
base_url = "http://www.baidu.com"
response = request.urlopen(base_url)
html = response.read().decode("utf-8")
with open("baidu.html","w",encoding="utf-8") as f:
f.write(html)