网络编程:用来实现网络互连的不同计算机运行程序可以进行数据交换
计算机网络之间以何种规则进行通信。分为OSI模型和TCP/IP参考模型
双方要遵守相同的协议,才能进行信息交流
三次握手
有网关,路由器
IP地址:有网络号段和主机号段。127.0.0.1:本机地址,0.0.0.0:任意地址。ping IP地址:测试与该IP地址是否相同
端口是软件的身份证,用来区分不同的软件,最大时2的16次方减一
#服务端配置
import socket
server = socket.socket()
server.bind(('127.0.0.1',8989)) #绑定要运行的服务端的IP地址,端口任意设置
server.listen(10) #设置最大监听数量
result = server.accept() #创建连接通道,获取对等套接字,返回的是一个元组,第一个是对等连接套接字,第二个是客户端的IP加上端口
conn,addr = result #拆包
conn.recv(1024) #设置最大接收字节数
conn.send(b'返回') #返回给客户端数据
#数据要对等
conn.close()
server.close()
#客户端配置
import socket
client = socket.socket()
client.connect(('127.0.0.1',8989)) #连接服务器开辟出的端口地址
client.send(b'hello') #发送字节数据
client.close()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h2okL5dq-1635859188331)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211020212829055.png)]
IO操作以何种规则进行操作,分为阻塞io,非阻塞io,多路复用io
阻塞IO就是专心做一件事情,阻塞的时候不做其他事情,做完这一件事情,才会去做其他事情。
#阻塞IO,同时建立两个套接字
import socket
server = socket.socket()
server.bind('127.0.0.1',8989)
server.listen(10)
all_conn = []
for i in range(2):
conn,addr = server.accept()
all_conn.append()
for conn in all_conn:
#得到所有的对等连接套接字
data = conn.recv(1024)
if data:
print(data)
else:
all_conn.remove(conn)
conn.close()
server.close()
#非阻塞IO
# -*- coding: utf-8 -*-
# @Time: 2021/10/29 19:19
# @Author: 枫无痕
# @Email: [email protected]
# @File: server01.py
# @Software: PyCharm
import socket
from time import sleep
server = socket.socket()
#设置为非阻塞套接字,需要i在其他操作之前设置
server.setblocking(False)
server.bind('127.0.0.1',8989)
server.listen(10)
# while True:
# try:
# conn,addr = server.accept()
# conn.recv(1024)
# except BlockingIOError:
# print("做其他事情")
# sleep(1)
all_conn = []
while True:
try:
conn,addr = server.accept()
conn.setblocking(False) #将对等套接字设置为非阻塞接字
all_conn.append(conn)
except BlockingIOError:
pass
except Exception as E:
print(f"发生了未知异常{E}")
#接收数据
for conn in all_conn:
try:
data = conn.recv(1024)
if data:
print(data)
conn.send(data)
else:
conn.close()
all_conn.remove(conn)
except BlockingIOError:
pass
except Exception as E:
print(f"发生了未知异常{E}")
雇佣人来查看与有没有上钩
原理:select/epoll这个function会不断轮询所负责的socket,有数据之后就会通知用户。
epoll是最佳的打工仔,是一个惰性事件回调,用户自己去调用,是linux最好的IO多路复用器,但是只有linux有。
#多路复用
import socket,selectors #IO多路复用选择器模块,
epoll_select = selectors.EpollSelector() #实例化
selectors.DefaultSelector() #默认选择器,自动根据不同操作系统选择
server = socket.socket()
server.bind('127.0.0.1',8989)
server.listen(10)
def f_accept(server):
conn,addr = server.accept() #生成对等连接套接字
epoll_select.register(conn, selectors.EVENT_READ, f_recv)
def f_recv(conn):
data = conn.recv(1024)
if data:
print(data)
else:
conn.close()
#selectors.EVENT_READ 有事件发生时,调用回调函数,第三个参数
epoll_select.register(server,selectors.EVENT_READ,f_accept)
while True:
events = epoll_select.select() #查询,返回的是一个列表,保存一个元组,
for key,mask in events:
func = key.data #函数体
conn = key.fileobj #已经注册的套接字
func(conn) #调用f_accept方法。
单进程:就是平常的执行顺序
多进程:就是如下所示
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
p1.start()
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
#一共耗时5秒钟。
多线程——跟多进程模块是差不多的。
import time
import threading
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
print('main_start',new_time())
p1 = threading.Thread(target=func,args=(1,2))
p1.start()
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
GIL全局解释锁——让任何一个进程中只有一个线程去执行。相当于是并发。
import socket
import multiprocessing
'''
主进程左连接客户端,生成对等套接字,通道连接
创建一个子进程,接收客户端
'''
def f_recv(conn):
while True:
data = conn.recv(1024)
if data:
print(data)
conn.send(data)
else:
conn.close()
break
def f_accept():
sever = socket.socket()
sever.bind(('127.0.0.1',4546))
sever.listen(10)
while True:
conn,addr =sever.accept()
p1 = multiprocessing.Process(target=f_recv,args=(conn,))
p1.start()
if __name__=='__main__':
f_accept()
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
p1.start()
p1.join() #等待子任务执行完毕,会进行阻塞
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print(multiprocessing.current_process()) #获取当前进程对象
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
p1.start()
p1.join() #等待子任务执行完毕,会进行阻塞
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
print(p1.name)
p1.name='进程一号'
print(p1.name)
p1.start()
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
p1.start()
time.sleep(5)#模拟耗时操作,
p1.terminate() #终止p1子进程
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
print('before start',p1.pid)
p1.start()
print('after start', p1.pid)
time.sleep(5)#模拟耗时操作,
p1.terminate() #终止p1子进程
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2))
print(p1.is_alive())
p1.start()
print(p1.is_alive())
p1.join()
print(p1.is_alive())
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
import time
import multiprocessing
def new_time():
return time.asctime(time.localtime(time.time()))
def func(x,y):
print(x+y)
print('func_start',new_time())
time.sleep(5)
print('func_end', new_time())
if __name__ == '__main__':
print('main_start',new_time())
p1 = multiprocessing.Process(target=func,args=(1,2),daemon=True) #开启守护模式
p1.start()
time.sleep(5)#模拟耗时操作,
print('main_end',new_time())
import redis
import multiprocessing
"""
自定义:
通过class关键字定一个类
要继承继承类
"""
class RedisProcess(multiprocessing.Process):
def __init__(self,db,key,values):
super().__init__()#调用父类的方法,创造子进程,实例化创建进程
self.connect = redis.StrictRedis(db=db) #本地连接,只需要指定一个数据库就可以
self.key = key
self.values = values
def set(self):
self.connect.set(self.key,self.values)
def get(self):
return self.connect.get(self.key)
def run(self):
self.set()
self.get()