python 19 socket循环、进程基础、并发
day 19 socket循环、进程基础、并发
昨日回顾
1.osi七层模型——>5层
-物理层
-0101电信号——>网线,光纤
-数据链路层
-网卡——>mac地址,全球唯一
-广播:局域网中通信
-网络层
-IP地址——>ipv4,ipv6
-子网掩码+ip区分是不是属于同一个局域网
-arp协议:iip和mac地址的映射表
-传输层
-端口:0-65535
-端口是用来区分应用程序
-TCP:可靠传输,三次握手,四次挥手
-UDP:不可靠传输
-应用层
2.常用的端口号
-80:http协议,tcp
-3306
-53:dns(域名解析),udp
3.TCP/IP————>socket抽象层——>针对于程序员来写客户端服务端程序,更好些。
4.基于TCP的套接字的客户端和服务端
-服务端
-实例化一个socket对象sk
-绑定一个ip和端口bind(元组的形式)
-监听listen(给一个队列可以容纳几个)
-等待连接accept,返回conn和addr
-数据传输read(conn.revc)和write(conn.send)
-连接断开(conn.close)
-socket断开(sk.close)
-客户端
-实例化一个socket对象client
-通过ip和端口连接服务端(connect)
-数据传输read和write
-断开连接client.close
1.加入连接循环的套接字服务端
import socket
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.bind(('localhost', 9000))
sk.listen(2)
while True:
conn, addr = sk.accept()
print(conn)
print(addr)
data = conn.recv(1024)
print(data.decode())
conn.send(data.upper())
conn.close()
sk.close()
import socket
client = socket.socket()
client.connect(('localhost', 9000))
client.send('傻逼'.encode())
data = client.recv(1024)
print(data.decode())
client.close()
2.加入通信循环的套接字服务端
import socket
sk = socket.socket()
sk.bind(('localhost', 9000))
sk.listen()
while True:
conn, addr = sk.accept()
while True:
try:
data = conn.revc(1024)
if not data:break
print(data.decode())
conn.send(data.upper())
except Exception as e:
print(e)
break
3.基于UDP的套接字客户端和服务端
# 基于UDP的套接字服务端
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(("localhost", 9000))
# 不需要listen,也不需要建立链接
while True:
# 获取用户发的数据即地址
data, addr = sk.recvfrom(1024)
print(data.decode())
sk.sendto(data.upper(), addr)
sk.close()
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
client.sendto("sb".encode(), ("localhost", 9000))
# data, addr = client.recvfrom(1024)
data = client.recv(1024)
print(data.decode())
client.close()
4.操作系统发展史
1.手工操作——穿孔卡片
-用户独占全机
-CPU的利用不充分
2.批处理——磁带存储
-把一个操作整个写到磁带中,以后要进行这个操作,直接拿磁带读入即可
-脱机批处理
-联机批处理
3.多道程序系统
-当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序。
-各道程序轮流地用CPU,并交替运行。
4.分时系统
-多个 程序在运行,时间片的概念,CPU执行完固定的时间就会转去另一个程序
5.通用操作系统
多道批处理系统,分时
io操作:(通通不占用CPU)
键盘输入,从硬盘拿数据,从网络加载数据——>都叫输入
显示在显示器,写入硬盘,从网络发送数据——>都叫输入
5.进程基础
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元。
# 进程是资源分配的最小单位,线程是CPU执行的最小单位
# 一个程序运行,最少有一个进程
# 一个进程里最少一条线程
# 进程和程序的区分
程序可以作为一种软件资料长期存在,而进程是有一定生命期的。
程序是永久的,进程是暂时的。
# 进程的状态
-就绪态:可以被CPU调度执行了,还没有执行,排着队
-运行态:在CPU中运行,正在运行(如果到了时间片,也会被调度出去,调度出去的程序就是就绪态)
-阻塞态:IO操作,把数据加载到内存中
![167-åæ¥å¼æ¥é»å¡éé»å¡-02.png](day 19 .assets/167-同步异步阻塞非阻塞-02.png)
6.并发和并行
并发:你在跑步,鞋带开了,停下跑步,系鞋带,系完之后,继续跑步,在一个时间段来看,同时执行
-单核下的并发
并行:你在跑步,同时听着歌,在同一时刻,在干多个事
-只有多核才涉及到并行
from multiprocessing import Process, Pool
import time
def w_file(s):
time.sleep(5)
with open('a.txt', 'a') as f:
print(s)
f.write(s)
f.write('\n')
# 如果再windows下开多进程,必须谢main,否则报错
if __name__ == '__main__':
time.sleep(5)
# 开启多进程的第一个方式
p = Process(target=w_file, args=('lll is lem'))
# 执行该进程
p.start()
# 又开了一个进程
p = Process(target=w_file, args=('xxx is xxx'))
# 执行该进程
p.start()
作业
1.写一个支持并发的TCP套接字服务端(可以有多个客户端同时跟服务端交互)
# 服务端
import socket
from multiprocessing import Process
def reply(conn, addr):
while True:
try:
data = conn.recv(1024)
print(addr, ':', data.decode())
conn.send(data.upper())
except Exception as e:
print(e)
break
if __name__ == '__main__':
sk = socket.socket()
sk.bind(("localhost", 9000))
sk.listen(5)
print("等待客户端连接")
while True:
conn, addr = sk.accept()
print("客户端已连接", addr)
p = Process(target=reply, args=(conn, addr))
p.start()
# 客户端
import socket
client = socket.socket()
client.connect(("localhost", 9000))
while True:
msg = input("输入客户端消息:")
if msg == 'q':
break
client.send(msg.encode())
data = client.recv(1024)
print(data.decode())
client.close()