3/28课后总结
基于tcp协议的套接字编程
客户端
import socket
client = socket.socket()
client.connect(('192.168.1.171', 9000))
client.send('准备开始'.encode('utf-8'))
while True:
server_data = client.recv(1024)
data = server_data.decode('utf-8')
if data == '接受到了':
print('服务端已经%s' % data)
value = input('请输入您想传输的值>>>').strip()
if not value:
client.send(' '.encode('utf-8'))
continue
client.send(value.encode('utf-8'))
else:
print('服务端已经%s' % data)
break
client.close()
服务端
import socket
server = socket.socket()
# 192.168.1.171
server.bind(('192.168.1.171', 9000))
server.listen(5)
while True:
conn, client_addr = server.accept()
while True:
try:
data = conn.recv(1024)
print(data.decode('utf-8'))
if data.decode('utf-8') == '结束':
conn.send('断开此次连接'.encode('utf-8'))
break
conn.send('接受到了'.encode('utf-8'))
except Exception as e:
print(e)
break
conn.close()
server.close()
基于udp协议的套接字编程
客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto('准备开始'.encode('utf-8'),('192.168.1.171', 9000))
while True:
server_data, server_addr = client.recvfrom(1024)
data = server_data.decode('utf-8')
if data == '接受到了':
print('服务端已经%s' % data)
value = input('请输入您想传输的值>>>').strip()
if not value:
client.send(' '.encode('utf-8'))
continue
client.sendto(value.encode('utf-8'),server_addr)
else:
print('服务端已经%s' % data)
break
client.close()
服务器
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 192.168.1.171
server.bind(('192.168.1.171', 9000))
while True:
conn, client_addr = server.recvfrom(1024)
print(conn.decode('utf-8'))
if conn.decode('utf-8') == '结束':
server.sendto('断开此次连接'.encode('utf-8'),client_addr)
server.sendto('接受到了'.encode('utf-8'),client_addr)
server.close()
粘包现象
data = conn.recv(1024) # 代表一次最大接受这么大的字节数
# 如果客户端发送的数据超过了1024字节,那么,服务端无法接收全部的,数据则会丢失
进程概念
# 进程比较抽象
程序是一堆代码,没有生命周期
进程是动态的,有生命周期
eg:
"""
厨师做饭,要按照菜谱来做,菜谱就是做菜的方法,厨师做饭的过程就是进程,厨师在这个过程中其实就是真实做事的人,进程不是实际做事的。在这个过程中,厨师就是线程,线程才是真正干事情的,做饭的过程中可以有多个干事的人,其实背后就是在一个进程中,可以有多个线程
"""
# 在这里面,菜谱其实就是进程,而厨师就是所谓的线程:真正做事的人
进程与线程的关系就是先开进程,然后在开线程
# 一个进程可以有多个线程,但是一个进程也至少要有一个线程
# 进程和线程是操作系统中的一个基本概念,进程和线程全部都是操作系统来调用的
单个cpu一次只能运行一个进程
"""
如果一个进程中只有一个线程那么这个线程就是主线程,主线程里会可能有许多个子线程
还有一个概念就是协程,协程就是单线程下的并发,比线程还小,消耗的资源也更小
"""
调度顺序: 进程 > 线程 > 协程(程序员调度的)
补充点:
CPU的工作机制:
# 当遇到i/o阻塞的时候,会自动剥夺CPU的执行权限
# 当CPU遇到占用时间过长的时候也会自动剥夺CPU的执行权限
# CPU的工作其实是来回切换的
i/o密集型:
# 有阻塞但是不会一直占用系统资源,中间会有等待如sleep
计算密集型:
# 与上一个相反,无阻塞但是会占用大量系统资源
并行和并发的概念
"""
补充:操作系统中的4种算法
先来先服务算法(FCFS)
短进程优先算法(SPF)
时间片轮转算法(RR)
多级反馈队列算法(MFQ)
"""
并行:
# 同一时间,执行多个任务(单核CPU不能实现并行)
并发:
# 同一时间段,执行多个任务(高并发就是短时间内涌入大量客户)
面试题:如何解决高并发问题
同步异步与阻塞非阻塞
同步:依赖于上一次的结果,会等待执行
异步:不依赖上一次的结果,不会等待执行
阻塞:会挂起
非阻塞:不会挂起
1. 同步阻塞 ---------------> 效率最低
2. 同步非阻塞
3. 异步阻塞
4. 异步非阻塞----------------> 效率最高
time.sleep()
如何开启进程
from multiprocessing import Process
def write_file():
with open('a.txt', 'w', encoding='utf-8') as f:
f.write('helloworld')
# write_file()
# 在Windows系统中,开启进程必须写在__main__判断里面
# 主进程,子进程
if __name__ == '__main__':
# 让你开一个进程来执行写文件的任务
p = Process(target=write_file) # 实例化得出一个对象
# 调用一个方法来真正的开一个进程
p.start()
Process类的参数
from multiprocessing import Process
def write_file(a,b,c,name,age):
# with open('a.txt', 'w', encoding='utf-8') as f:
# f.write('helloworld')
print('a:', a)
print('b:', b)
print('c:', c)
print('name:', name)
print('age:', age)
# write_file(1)
# 在Windows系统中,开启进程必须写在__main__判断里面
# 主进程,子进程
if __name__ == '__main__':
'''
name=None, args=(), kwargs={},
'''
# 让你开一个进程来执行写文件的任务
p = Process(target=write_file, name='ly', args=(1,2,3), kwargs={'name':'ly', 'age':20}) # 实例化得出一个对象
# 调用一个方法来真正的开一个进程
p.start()
# 代表的是进程名字
print(p.name) # Process-1 ---->ly
标签:总结,utf,socket,28,server,client,课后,进程,data
From: https://www.cnblogs.com/juzixiong/p/17266359.html