网络基础 + 多线程(threading) + 解析 socketsever 源码
网络编程
1. 电脑里面有网卡,网卡里面有 mac 地址.
2. 插上网线以后, 路由器或交换机中的 DHCP 服务会自动分配 IP 地址.
• IP: 192.168.13.84 4个点分的十进制
IPv4
00000000.00000000.00000000.00000000
0~255 0~255 0~255 0~255
IPv6
00000000.00000000.00000000.00000000.00000000.00000000
• 子网掩码:255.255.255.0
IP: 192.168.13.84
掩码: 255.255.255.0
将挡住的IP位数作为网段.
未挡住的部分作为可变的值.
• 网关IP:192.168.13.1
路由器中连接交换机的口.
• 局域网内、城域网、广域网:
广播
单播
广播风暴
arp协议
3. DNS
• 网络连接:
- 域名解析
www.baidu.com 111.13.100.91
- 连接
sk = socket.socket()
sk.connect(('47.95.64.113',80))
...
• 问题来了,域名和IP的对应关系在哪里?
本地:
Win本地电脑:
C:\Windows\System32\drivers\etc\hosts
11.11.11.11 luffycicy.com
Linux/Mac电脑:
/etc/hosts
DNS服务器:全球顶级DNS服务器13台
www.luffycity.com 47.95. 4 .113
• 创业:
a. 租一个服务器(公有云和私有云)+公网IP + 租空间
b. 租域名
域名+IP解析
c. 写代码,然后上传到服务器,运行.
多线程 (threading)
多线程的使用,需要导入 import threading 模块.
1. 初识线程
比如说一个人即要去拿快递,又要和女朋友玩,还要取外卖,当事情做不过来的时候,可以开通多个线程,让其各自执行各自的命令,并且之间互不影响.
多线程中,包括主线程和子线程, 分别取执行命令的是子线程. 下面举一个简单的示例介绍下多线程.
import time
import threading
def task(a1,a2,a3):
time.sleep(2) # 为了使效果明显,让程序睡2秒
print('拿快递')
def play():
print('和女朋友去玩')
def wm():
print('去拿外卖')
# 创建一个线程 让该线程去执行任务:函数
t1 = threading.Thread(target=task,args=(1,2,3,)) # target 是要执行的函数
# args 是函数要传递的参数, 元组的形式,要加逗号如(1,)
t1.start() # 去执行吧
# 创建一个线程 让该线程去执行任务:函数
t2 = threading.Thread(target=play)
t2.start()
# 创建一个线程 让该线程去执行任务:函数
t3 = threading.Thread(target=wm)
t3.start()
print('玩扇子') # 主线程中做的事情.
print('煽风点火')
print('耍贱...')
2. 线程接收任务
import time
import threading
def task(n):
print('开始执行任务:',n)
time.sleep(5)
print('...')
print('任务%s 执行完毕:'%n)
while True:
name = input("请输入任务:")
t = threading.Thread(target=task,args=(name,))
t.start()
3. socket 和 线程配合
服务端配合, 以下示例是, 有人来连接便创建一个线程,取为其服务.
import time
import socket
import threading
def task(conn):
time.sleep(20)
data = conn.recv(1024)
print(data)
conn.close()
server = socket.socket()
server.bind(('172.0.0.1',8001,))
server.listen(5)
while True:
conn,addr = server.accept()
t = threading.Thread(target=task,args=(conn,))
t.start()
解析 socketserver 源码
1. socketserver 用法
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# self.request # 自定义
# self.client_address
# self.server
# 编写代码
server = socketserver.ThreadingTCPServer(('192.168.13.84',8001,),MyServer)
# 方法的调用
# server.server_address = server_address
# server.RequestHandlerClass = RequestHandlerClass
# server.__is_shut_down = threading.Event()
# server.__shutdown_request = False
# server.socket = socket....
# - socket.bind
# - socket.listen
server.serve_forever()
总结:
通过 socketserver 要学会看源码,明白里面的机制, 非常重要
2. 从网站上下载图片, 图片是存放在服务器上的,
图片的地址示例为: https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg
通过解析域名得到服务器的 IP 地址, 从服务器端下载图片.
"""
pip3 install requests # 终端运行这个命令,安装 requests
"""
import threading
import requests # 需要在终端安装
import uuid
# 3张图片的地址放入列表中
url_list = [
'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg',
'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg',
'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg',
]
def task(url):
""""""
"""
1. DNS解析,根据域名解析出IP
2. 创建socket客户端 sk = socket.socket()
3. 向服务端发起连接请求 sk.connect()
4. 发送数据(我要图片) sk.send(...)
5. 接收数据 sk.recv(8096)
接收到数据后写入文件。
"""
ret = requests.get(url) # 得到的是接收后的数据
file_name = str(uuid.uuid4()) + '.jpg' # uuid.uuid4() 随机获取字符串
with open(file_name, mode='wb') as f:
f.write(ret.content)
for url in url_list:
t = threading.Thread(target=task,args=(url,))
t.start()
知识补充:
requests 模块
不是内置模块,使用时需要在终端(cmd)运行: pip3 install requests 命令
ret = requests.get (url) # url 为发送过去的图片地址, ret 为接收的数据
uuid 模块
uuid 可以通过 uuid4 随机获取字符串,类似 random 随机获取数字.
v = str(uuid.uuid4()) # v 就是获取后的字符串 转不转 str() 都可以
import uuid v = str(uuid.uuid4()) print(v) # 069038cd-effe-4fd2-8798-0e4ebfda9d50

浙公网安备 33010602011771号