1.计算机网络介绍
1.1 OSI七层模型
物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
1.2 TCP/IP协议
网络接口层,网络层,传输层,应用层
1.3 IP地址
对计算机而言,一个网络接口对应一个IP地址。
目前IP地址有两种:IPv4和IPv6。IPv4有2^32个不同的主机IP,IPv6将逐步取代IPv4。
IPv4有A,B,C,D,E五类地址:
A类地址范围:1.0.0.1——126.255.255.254
B类地址范围:128.0.0.1——191.255.255.254
C类地址范围:192.0.0.1——223.255.255.254
D类地址范围:224.0.0.1——239.255.255.254
E类地址范围:240.0.0.1——255.255.255.255
A,B,C三类地址用作单播地址,用于单个信源到单个目的的通信,D类地址为IP组播应用地址,E类地址为实验保留。
单播地址又有一部分是私有地址,不能与公共网络连接,私有地址为:
10.0.0.0——10.255.255.255
172.16.0.0——172.31.255.255
192.168.0.0——192.168.255.255
IPv4地址的构成:前8位,首字节,用于表示网络ID。后24位,表示主机ID。如果后24位全是0或者1的话,表示的是网络地址和广播地址。
1.4 子网掩码
一个组织只有2台机器,只占用两个IP,其他的IP不是浪费了吗?此时需要子网掩码。
子网掩码:用主机ID的位数来标识网络ID,从而对IP地址进行更细的分类。通常1表示网络位,0表示主机位
1.5 域名
主要是方便记忆,IP太难记了。而将域名和IP对应起来,需要通过DNS域名解析器。
2.python底层网络模块
2.1 Socket
计算机编程都离不开一个基本的组件:套接字(socket)
套接字接口以IP地址及通信端口组成套接字地址(socket Address),远程的套接字地址和本地的套接字地址完成连线后,再加上使用的协议(protocal),这个五元组(来源IP,目的IP,来源端口,目的端口,协议)作为套接字对就可以彼此交换数据了。
套接字本质是操作系统提供的一种进程间通信机制,是主机或者不同进程间可以通信。
2.2 socket模块
套接字格式:
#套接族,套接字类型,协议编号(默认0)
socket(family,type[,protocal])
套接字族:AF_UNIX(同一台机器),AF_INET(仅用于IPV4),AF_INET6(仅用于IPV6),AF_UNISPEC(指定主机名和服务名,并且适合任何协议族的地址)
套接字类型:SOCK_STREAM(TCP协议),SOCK_DGRAM(UDP协议),SOCK_RAW(原始套接字)
创建TCP socket:
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
创建UDP socket:
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
建立socket对象后,还需要建立监听。
sock.bind(("127.0.0.1",999))
sock.listen(backlog)
backlog:最多连接数。
accept方法:等待客户请求连接
connection address= socks.accept()
2.3 socket对象方法
2.3.1 服务端可以使用的方法
s.bind():绑定地址到套接字
s.listen():开始TCP监听
s.accept():被动接受TCP客户端请求
2.3.2 客户端可以使用的方法
s.connect():主动初始化TCP服务连接
s.connect_ex():连接出错时返回错误码而不是抛出异常
2.3.3 公共用途方法
s.recv():接收TCP数据,以字符串形式返回
s.send():发送TCP数据,字符串发送
s.sendall():发送完整TCP数据
s.recvfrom():接收UDP数据
s.sendto():发送UDP数据
s.close():关闭套接字
s.getsockname():返回套接字地址
s.setsockopt(level,optname,value):设置套接字选项的值
s.getsockopt(level,optname,value):返回套接字选项的值
s.getpeername():返回套接字远程地址
s.getsockname():返回套接字自己地址
s.settimeout(timeout):设置超时时间
s.gettimeout():返回超时时间
s.fileno():返回套接字的文件描述符
s.setblocking(flag):是否阻塞状态
s.makefile():创建与套接字相关联的文件
3.TCP编程
3.1 客户端
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(("www.baidu.com",80))
sock.send(b"GET/HTTP/1.1\r\nHOST:www.baidu.com\r\nConnection:close\r\n\r\n")
buffer = []
while True:
content = sock.recv(1024)
if content:
buffer.append(content)
else:
break
web_content = b"".join(buffer)
print(web_content)
#分隔http协议头,保存的html文件不包含http协议头
http_header,http_content = web_content.split(b"\r\n\r\n",1)
with open("baidu.html","wb") as f:
f.write(http_content)
3.2 服务端
import socket
import threading
def echo_server(client:socket.socket,address:tuple):
print("欢迎来自{}:{}的新客户端".format(address[0],address[1]))
client.send("Welcome from {}:{}\r\n".format(address[0],address[1]).encode("utf-8"))
while True:
content = client.recv(1024)
if content == b"exit":
break
elif content:
print(content.decode("utf-8"))
else:
break
print("客户端退出")
client.close()
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(("0.0.0.0",2018))
sock.listen(5)
print("server start !listening 0.0.0.0:2018")
while True:
client,address = sock.accept()
t = threading.Thread(target=echo_server,args=(client,address))
t.start()
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",2018))
client.send("i am client!".encode("utf-8"))
server_content = client.recv(1024)
print(server_content.decode("utf-8"))
client.send(b"exit")
client.close()
4.UDP编程
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server = ("127.0.0.1",2019)
sock.sendto("一起学python".encode("utf-8"),server)
sock.close()
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(("0.0.0.0",2019))
while True:
data,address = sock.recvfrom(1024)
print("收到来自{}:{}的信息:".format(address[0],address[1]))
print(data.decode("utf-8"))
5. urllib模块
5.1 GET请求
from urllib import request
#抓取百度
def fetch_baidu():
http_client = request.urlopen("http://www.baidu.com")
content = http_client.read()
print("HTTP Status:{},{}".format(http_client.status,http_client.reason))
print("HTTP Response headers:")
for k,v in http_client.getheaders():
print("{}:{}".format(k,v))
http_client.close()
return content.decode("utf-8")
def main():
content = fetch_baidu()
if __name__ == "__main__":
main()
5.2 post请求
import json
import pprint
from urllib import request,parse
def fetch_page():
username = "user"
password = "123"
#参数需要进行url转码
post_data = parse.urlencode([
("username",username),("password",password)
])
#构造Request对象
http_request = request.Request("http://httpbin.org/post")
http_request.add_header("Refer","python")
#data参数必须是bytes对象
http_request.data = post_data.encode("utf-8")
with request.urlopen(http_request) as http_response:
content = http_response.read()
result = json.loads(content.decode("utf-8"))
pprint.pprint(result)
def main():
fetch_page()
if __name__ == "__main__":
main()
6.requests模块介绍
首先需要导入:
conda install requests
import requests
r = requests.get("http://httpbin.org/get")
print(r.text)
#post参数只需要传递字典即可,不需要手动执行
r = requests.post('http://httpbin.org/post',data={'key':'value'})
print(r.text)
r = requests.put('http://httpbin.org/put',data={'key':'value'})
print(r.text)
r = requests.delete('http://httpbin.org/delete')
print(r.text)
r = requests.head('http://httpbin.org/get')
print(r.text)
r = requests.options('http://httpbin.org/get')
print(r.text)