网络编程基础概念
第一个网络通信
server端
import socket
sk = socket.socket()
sk.bind(('192.168.121.1', 9000))
sk.listen()
conn, adder = sk.accept()
conn.send(b'hello')
msg = conn.recv(1024)
print(msg)
conn.close()
sk.close()
client端
import socket
sk = socket.socket()
sk.connect(('192.168.121.1', 9000))
msg = sk.recv(1024)
print(msg)
sk.send(b'byebye')
sk.close()
协议概念
udp
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1', 8666))
while True:
msg, adder = sk.recvfrom(1024)
if msg.decode('utf-8').lower() == 'q':
continue
print(msg.decode('utf-8'))
send_msg = input('请输入:')
sk.sendto(send_msg.encode('utf-8'), adder)
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
server = ('127.0.0.1', 8666)
while True:
send_msg = input('请输入:')
sk.sendto(send_msg.encode('utf-8'), server)
if send_msg.lower() == 'q':
print('会话结束')
break
msg = sk.recv(1024).decode('utf-8')
if msg.lower() == 'q':
print('会话结束')
break
print(msg)
tcp
初识
import socket
sk = socket.socket()
sk.bind(('192.168.121.1', 9000))
sk.listen()
conn, adder = sk.accept()
while True:
send_msg = input('请输入:')
conn.send(send_msg.encode('utf-8'))
if send_msg.upper() == 'Q':
break
msg = conn.recv(1024).decode('utf-8')
if msg.upper() == 'Q':
break
print(msg)
conn.close()
sk.close()
import socket
sk = socket.socket()
sk.connect(('192.168.121.1', 9000))
while True:
msg2 = sk.recv(1024).decode("utf-8")
if msg2.upper() == 'Q':
break
print(msg2)
send_msg = input("请输入:")
sk.send(send_msg.encode('utf-8'))
if send_msg.upper() == 'Q':
break
sk.close()
tcp中的现象
- 不知道对方传输的字节大小
- 使用struct模块,转换为4字节
-
- 转:struct.pack(‘i’, len(msg2))
-
- 现接收字节大小:le = sk.recv(4)
-
- 再转为原来字节:struct.unpack(‘i’, le)[0] (注意返回的是元组, 所以取第一个)
- 每条信息都要转
import socket
import struct
sk = socket.socket()
sk.bind(('127.0.0.1', 8666))
sk.listen()
conn, adder = sk.accept()
msg1 = input(">>>").encode('utf-8')
msg2 = input('>>>').encode('utf-8')
blen = struct.pack('i', len(msg1))
conn.send(blen)
conn.send(msg1)
blen = struct.pack('i', len(msg2))
conn.send(blen)
conn.send(msg2)
conn.close()
sk.close()
import socket
import struct
sk = socket.socket()
sk.connect(('127.0.0.1', 8666))
le = sk.recv(4)
le = struct.unpack('i', le)[0]
msg1 = sk.recv(le).decode('utf-8')
print(msg1)
le = sk.recv(4)
le = struct.unpack('i', le)[0]
msg2 = sk.recv(le).decode('utf-8')
print(msg2)
sk.close()
struct模块
import struct
num = 1234568
num2 = 123
num3 = 8
ret = struct.pack('i', num)
print(len(ret))
de = struct.unpack('i', ret)
print(de)
ret = struct.pack('i', num2)
print(len(ret))
de = struct.unpack('i', ret)
print(de)
ret = struct.pack('i', num3)
print(len(ret))
de = struct.unpack('i', ret)
print(de)
-----------------------------
4
(1234568,)
4
(123,)
4
(8,)
-----------------------------
tcp文件传输
import json
import socket
import struct
sk = socket.socket()
sk.bind(('127.0.0.1', 9696))
sk.listen()
conn, _ = sk.accept()
msg_len = conn.recv(4)
msg_len = struct.unpack('i', msg_len)[0]
msg = conn.recv(msg_len)
msg = json.loads(msg)
with open(msg['filename'], 'wb') as f:
while msg['filesize'] > 0:
content = conn.recv(1024)
msg['filesize'] -= len(content)
f.write(content)
conn.close()
sk.close()
import json
import socket
import os
import struct
sk = socket.socket()
sk.connect(('127.0.0.1', 9696))
abs_path = r'D:\PyCharmProject\python-核心编程\hehe'
filename = os.path.basename(abs_path)
filesize = os.path.getsize(abs_path)
dic = {'filename': filename, 'filesize': filesize}
str_dic = json.dumps(dic)
b_dic = str_dic.encode('utf-8')
mlen = struct.pack('i', len(b_dic))
sk.send(mlen)
sk.send(b_dic)
with open(abs_path, 'rb') as f:
while filesize > 0:
content = f.read(1024)
filesize -= 1024
sk.send(content)
sk.close()
验证客户端的合法性
# # 随机生成一个字符串
# import os
# ret = os.urandom(16)
# print(ret)
#
# import hashlib
# sha = hashlib.sha1(秘钥)
# sha.update(随机字符串)
# result = sha.hexdigest()
# 第二种方法
import hashlib
import hmac # 替代hashlib模块
import os
# 秘钥+随机字符串
h = hmac.new(b'alex_sb', os.urandom(32), hashlib.sha256)
ret = h.digest()
print(ret)
-
server import hashlib
import os
import socket
secret_key = b'alex_sb'
sk = socket.socket()
sk.bind(('127.0.0.1', 9696))
sk.listen()
conn, adder = sk.accept()
rand = os.urandom(32)
conn.send(rand)
sha = hashlib.sha1(secret_key)
sha.update(rand)
res = sha.hexdigest()
res_client = conn.recv(1024).decode('utf-8')
if res_client == res:
print('是合法客户端')
conn.send(b'hello')
else:
conn.close()
-
client
import socket
import hashlib
secret_key = b'alex_sb'
sk = socket.socket()
sk.connect(('127.0.0.1', 9696))
rand = sk.recv(32)
sha = hashlib.sha1(secret_key)
sha.update(rand)
res = sha.hexdigest()
sk.send(res.encode('utf-8'))
msg = sk.recv(1024).decode('utf-8')
print(msg)
socketserver
import time
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request
while True:
try:
content = conn.recv(1024).decode('utf-8')
conn.send(content.upper().encode('utf-8'))
time.sleep(0.5)
except ConnectionError:
break
server = socketserver.ThreadingTCPServer(('127.0.0.1', 9696), MyServer)
server.serve_forever()
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 9696))
while True:
sk.send('i love you'.encode('utf-8'))
msg = sk.recv(1024).decode('utf-8')
print(msg)
多线程
进程
1.概念
# multiple 多元化的
# processing 进程
# multiprocessing 多远的处理进程的模块
# from multiprocessing import Process
# import os
#
#
# def func():
# print(os.getpid(), os.getppid())
# # pid process id 进程id
# # ppid parent process id 父进程id
#
#
# if __name__ == '__main__':
# # 只会在子主进程中执行所有的代码,你写在name=main下
# print('main:', os.getpid(), os.getppid())
# p = Process(target=func)
# p.start()
# 为什么要用if __name__ == '__main__':
# a = 1
# 能不能给子进程传递参数
# from multiprocessing import Process
# import os
#
#
# def func(name, age):
# print(os.getpid(), os.getppid(), name, age)
#
#
# if __name__ == '__main__':
# # 只会在子主进程中执行所有的代码,你写在name=main下
# print('main:', os.getpid(), os.getppid())
# p = Process(target=func, args=('李锦彪', 84)) # 传参
# p.start()
# 能不能获取子进程的返回值
# 不能
# 能不能同时开启多个子进程
# 可以
# import time
# from multiprocessing import Process
# import os
#
#
# def func(name, age):
# print('%s start' % name)
# time.sleep(1)
# print(os.getpid(), os.getppid(), name, age)
#
#
# if __name__ == '__main__':
# # 只会在子主进程中执行所有的代码,你写在name=main下
# print('main:', os.getpid(), os.getppid())
# arg_lit = [('ljn', 54), ('jv', 12), ('hdhd', 11)]
# for i in arg_lit:
# p = Process(target=func, args=i) # 传参
# p.start() # 异步非阻塞
# join的用法
# import time
# from multiprocessing import Process
#
# def func(name, age):
# print('%s 的年龄: %d' % (name, age))
# time.sleep(1)
# print('发送完毕')
#
# if __name__ == '__main__':
# arg_lit = [('李锦彪', 18), ('黄欣宇', 12), ('锦欣宇', 11)]
# p_lst = []
# for i in arg_lit:
# p = Process(target=func, args=i) # 传参
# p.start() # 异步非阻塞
# p_lst.append(p)
# for p in p_lst:
# p.join() # 阻塞:直到p这个进程执行完,才继续执行代码
# print('所有的邮件发送完毕')
# 同步阻塞,异步非阻塞
# 同步阻塞:join
# 异步非阻塞:start
# 多进程之间的数据是否隔离 是
# from multiprocessing import Process
# n = 0
# def func():
# global n
# n += 1
#
# if __name__ == '__main__':
# p_1 = []
# for i in range(0, 100):
# p = Process(target=func)
# p.start()
# p_1.append(p)
# for p in p_1:
# p.join()
# print(n)
# 使用多进程实现一个并发的socket的server
#
2.多进程实现一个并发的socket的server
server:
import socket
from multiprocessing import Process
def talk(conn):
while True:
msg = conn.recv(1024).decode('utf-8')
print(msg)
ret = msg.upper().encode('utf-8')
conn.send(ret)
conn.close()
if __name__ == '__main__':
sk = socket.socket()
sk.bind(('127.0.0.1', 9999))
sk.listen()
while True:
conn, adder = sk.accept()
Process(target=talk, args=(conn, )).start()
sk.close()
client:
import socket
import time
sk = socket.socket()
sk.connect(('127.0.0.1', 9999))
while True:
sk.send(b'hello')
msg = sk.recv(1024).decode('utf-8')
print(msg)
time.sleep(0.5)
sk.close()
3.开启进程的另一种方法
import os
import time
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
super().__init__()
def run(self):
time.sleep(1)
print(os.getpid(), os.getppid(), self.a, self.b, self.c)
if __name__ == '__main__':
print('-->', os.getpid())
for i in range(10):
p = MyProcess(11, 2, 3)
p.start()
4.process类的其他方法
import os
import time
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
super().__init__()
def run(self):
time.sleep(1)
print(os.getpid(), os.getppid(), self.a, self.b, self.c)
if __name__ == '__main__':
print('-->', os.getpid())
p = MyProcess(11, 2, 3)
p.start()
print(p.pid, p.ident)
print(p.name)
print(p.is_alive())
p.terminate()
print(p.is_alive())
time.sleep(0.01)
print(p.is_alive())
5.守护进程
import time
from multiprocessing import Process
def son1():
while True:
print('-->is son1')
time.sleep(1)
def son2():
for i in range(10):
print('in son2')
time.sleep(1)
if __name__ == '__main__':
p1 = Process(target=son1)
p1.daemon = True
p1.start()
p2 = Process(target=son2)
p2.start()
time.sleep(3)
print('in main 守护进程结束')
6.锁
import time
from multiprocessing import Process, Lock
import json
def search(i):
with open('ticket', encoding='utf-8') as f:
ticket = json.load(f)
print('%s :当前的余票是%s张' % (i, ticket['count']))
def buy_ticket(i):
with open('ticket', encoding='utf-8') as f:
ticket = json.load(f)
if ticket['count'] > 0:
ticket['count'] -= 1
print('%s 买到票了' % i)
time.sleep(0.1)
with open('ticket', mode='w', encoding='utf-8') as f:
json.dump(ticket, f)
def get_lock(i, lock):
with lock:
search(i)
buy_ticket(i)
if __name__ == '__main__':
lock = Lock()
for i in range(10):
Process(target=get_lock, args=(i, lock)).start()
7.队列
生产者消费者模型
import random
import time
from multiprocessing import Process,Queue
def consumer(q, name):
while True:
food = q.get()
if food:
print('%s 吃了 %s' % (name, q.get()))
else: break
def producer(q, name, food):
for i in range(10):
foodi = '%s%s' % (food, i)
print('%s 生产了 %s' % (name, foodi))
time.sleep(random.random())
q.put(foodi)
if __name__ == '__main__':
q = Queue()
p = Process(target=consumer, args=(q, '李锦彪'))
p1 = Process(target=producer, args=(q, '黄欣宇', '黄金'))
p2 = Process(target=producer, args=(q, '锦欣宇', '西瓜'))
p.start()
p1.start()
p2.start()
p1.join()
p2.join()
q.put(None)
8.异步阻塞
生产者消费者模型
线程
1.threading模块
from threading import Thread
n = 100
def func():
global n
n -= 1
t_1 = []
for i in range(100):
t = Thread(target=func)
t.start()
t_1.append(t)
for i in t_1:
i.join()
print(n)
2.守护线程
import time
from threading import Thread
def son():
while True:
print('in son')
time.sleep(1)
def sons():
for i in range(10):
print('in sons****')
time.sleep(1)
if __name__ == '__main__':
t = Thread(target=son)
t.daemon = True
t.start()
Thread(target=sons).start()
3.线程锁
import time
from threading import Thread, Lock
n = 0
def add(lock):
with lock:
for i in range(5520000):
global n
n += 1
def sub(lock):
with lock:
for i in range(5520000):
global n
n -= 1
if __name__ == '__main__':
t_1 = []
lock = Lock()
for i in range(2):
t1 = Thread(target=add, args=(lock,))
t1.start()
t2 = Thread(target=sub, args=(lock,))
t2.start()
t_1.append(t1)
t_1.append(t2)
for i in t_1:
i.join()
print(n)
4.单例模式
import time
from threading import Thread
class A:
from threading import Lock
__instance = None
lock = Lock()
def __new__(cls, *args, **kwargs):
with cls.lock:
if not cls.__instance:
time.sleep(0.00001)
cls.__instance = super().__new__(cls)
return cls.__instance
def func():
a = A()
print(a)
if __name__ == '__main__':
for i in range(10):
Thread(target=func).start()
5.递归锁和死锁
import time
from multiprocessing import Process, RLock, Lock
from threading import Thread
noodle_lock = Lock()
fork_lock = RLock()
def eat(name):
fork_lock.acquire()
print(name, '抢到面了')
print(name, '抢到叉子了')
print(name, '吃面')
time.sleep(1)
fork_lock.release()
print(name, '放下叉子了')
print(name, '放下面了')
def eat2(name):
fork_lock.acquire()
print(name, '抢到叉子了')
print(name, '抢到面了')
print(name, '吃面')
fork_lock.release()
print(name, '放下面了')
print(name, '放下叉子了')
if __name__ == '__main__':
Thread(target=eat, args=('李锦彪',)).start()
Thread(target=eat2, args=('黄欣宇',)).start()
Thread(target=eat, args=('锦欣宇',)).start()
Thread(target=eat2, args=('二蛋',)).start()
6.队列
import queue
q = queue.Queue(4)
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
try:
q.get_nowait()
except Exception as e:
print(e)
print('队列为空继续其他内容')
print('*' * 50)
from queue import LifoQueue
lq = LifoQueue()
lq.put(1)
lq.put(2)
lq.put(3)
print(lq.get())
print(lq.get())
print(lq.get())
print('*' * 50)
from queue import PriorityQueue
priq = PriorityQueue()
priq.put((1, 'a'))
priq.put((5, 'b'))
priq.put((6, 'x'))
priq.put((4, 'y'))
print(priq.get())
print(priq.get())
print(priq.get())
print(priq.get())
7.池
import random
import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import current_thread
def func(name, n):
print(name, current_thread().ident, n)
time.sleep(random.randint(1, 3))
tp = ThreadPoolExecutor(20)
for i in range(20):
tp.submit(func, '李锦彪', 2)
协程
1.协程概述
数据库
1.初识
2.表操作
3.索引
4.pymysql模块
必须的步骤
conn = pymysql.connect(host='',user='',password='',database='');
cur = conn.cursor()
ret = cur.execute('sql....')
cur.execute('sql....')
cur.commit()
print(cur.rowcount)
cur.close()
conn.close()
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='187365', database='ljb')
cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
5.事务、锁
web服务
1.初识http
服务器
import socket
sk = socket.socket()
sk.bind(('127.0.0.1', 9696))
sk.listen()
while 1:
conn, adder = sk.accept()
mvg = conn.recv(1024).decode('utf-8')
print(mvg)
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
with open('my.html', 'rb') as f:
data = f.read()
conn.send(data)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>你好!世界</h1>
</body>
</html>
get方法
post方法
2、web框架
import socket
from threading import Thread
import time
sk = socket.socket()
sk.bind(('127.0.0.1', 9696))
sk.listen()
def html(conn):
time_target = str(time.time())
with open('my-2.html', 'r', encoding='utf-8') as f:
data = f.read()
data = data.replace('$xxoo$', time_target)
data = data.encode('utf-8')
conn.send(data)
conn.close()
def css(conn):
with open('test.css', 'rb') as f:
data = f.read()
conn.send(data)
conn.close()
def js(conn):
with open('javascript.js', 'rb') as f:
data = f.read()
conn.send(data)
conn.close()
def jpg(conn):
with open('1.jpg', 'rb') as f:
data = f.read()
conn.send(data)
conn.close()
def ico(conn):
with open('1.ico', 'rb') as f:
data = f.read()
conn.send(data)
conn.close()
def jqurey(conn):
with open('jquery-3.6.0.js', 'rb') as f:
data = f.read()
conn.send(data)
conn.close()
urlpatterns = [
('/', html),
('/test.css', css),
('/1.jpg', jpg),
('/1.ico', ico),
('/javascript.js', js),
('/jquery-3.6.0.js', jqurey)
]
while 1:
conn, adder = sk.accept()
request_mvg = conn.recv(1024).decode('utf-8')
path = request_mvg.split('\r\n')[0].split(' ')[1]
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
for i in urlpatterns:
if path == i[0]:
print(path)
Thread(target=i[1], args=(conn,)).start()
ket from threading import Thread import time
sk = socket.socket() sk.bind((‘127.0.0.1’, 9696)) sk.listen()
def html(conn): time_target = str(time.time()) with open(‘my-2.html’, ‘r’, encoding=‘utf-8’) as f: # 读取html,以字符串形式读取,以便后续操作(动态) data = f.read() # 读取字符串 data = data.replace(‘
x
x
o
o
xxoo
xxoo’, time_target) # 替换 data = data.encode(‘utf-8’) conn.send(data) # 发送html conn.close()
def css(conn): with open(‘test.css’, ‘rb’) as f: data = f.read() conn.send(data) conn.close()
def js(conn): with open(‘javascript.js’, ‘rb’) as f: data = f.read() conn.send(data) conn.close()
def jpg(conn): with open(‘1.jpg’, ‘rb’) as f: data = f.read() conn.send(data) conn.close()
def ico(conn): with open(‘1.ico’, ‘rb’) as f: data = f.read() conn.send(data) conn.close()
def jqurey(conn): with open(‘jquery-3.6.0.js’, ‘rb’) as f: data = f.read() conn.send(data) conn.close()
urlpatterns = [ # 反射准备 (‘/’, html), (‘/test.css’, css), (‘/1.jpg’, jpg), (‘/1.ico’, ico), (‘/javascript.js’, js), (‘/jquery-3.6.0.js’, jqurey) ]
while 1: conn, adder = sk.accept() # 等待接收信息 request_mvg = conn.recv(1024).decode(‘utf-8’) # 接收信息
path = request_mvg.split('\r\n')[0].split(' ')[1] # 网页需要请求的路径
conn.send(b'HTTP/1.1 200 ok\r\n\r\n') # http请求信息:协议/版本 状态码 状态码原因短语
for i in urlpatterns:
if path == i[0]:
print(path)
Thread(target=i[1], args=(conn,)).start() # 线程处理并发
|