1.UDP套接字
注意:
udp是无链接的,先启动哪一端都不会报错
因为udp协议无连接,所以发送数据格式为client.sendto(消息内容,服务器IP与端口的元组)
接收数据格式:data,client_addr=server.recvfrom(1024)
data为接收到的数据,client_addr为发送者的IP与端口的元组,用以回复消息
因为udp没有链接,所以客户端可以同时向服务端发送数据,服务端挨个处理这些数据并返回,从而实现并发,但这有很大的局限性,比如处理数据的时间比较长,那么后面的一个客户端会明显感觉到等待udp协议不会出现粘包
UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。
所以udp协议不用自定报头部分,提高了传输效率udp协议不可靠
发送数据是将数据从应用程序的内存中拷贝到系统内存中,通过网卡发送出去的
tcp协议发数据是拷贝一份数据发出去,等着对方回复一个ACK才会把系统内存中的的数据删掉,如果没收到对方的ACK,那么过段时间还会继续发
而UDP协议是直接将数据发出去,系统内存中不做保留,他只负责发,对方爱收不收,所以会出现丢包
UDP协议的小程序示例
udp服务端
#导入socket模块
import socket
#创建服务器对象,socket.SOCK_DGRAM代表遵循UDP协议
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#绑定地址
server.bind(('127.0.0.1',8082))
#通信循环
while True:
#接收客户端发来的消息以及客户端IP与端口
data,client_addr=server.recvfrom(1024)
print(data)
#将消息转为大写回复给客户端,
#两个参数为回复信息与客户端IP与端口
server.sendto(data.upper(),client_addr)
server.close()
udp客户端
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
msg=input('>>: ').strip()
client.sendto(msg.encode('utf-8'),('127.0.0.1',8082))
data,server_addr=client.recvfrom(1024)
print(data)
2.socketserver实现并发
基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环
只有通信循环结束才能建立下一次连接,就好比是开了一个饭店,一个人在外面揽客,揽到客人以后自己又要去厨房做菜,还要等客人吃完结完账才能继续出去揽下一位客人,所以实现并发的思路就是 : 让一个人专门在门口揽客,有客人后交给服务员,让他去处理,自己继续揽客,又来了客人后再交给另外一个服务员
server=socketserver.ThreadingTCPServer(参数一,参数二)
参数一为服务端绑定的IP以及端口
参数二为自定义的类来处理通信循环的
server.serve_forever() # 链接循环
- 自定义的类必须继承
socketserver.BaseRequestHandler
- 自定义的类必须有
handle(self)
方法用来处理通信循环
基于tcp通信实现并发示例
服务端:
import socketserver
# 自定义类用来处理通信循环
class MyTCPhanler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
data = self.request.recv(1024)
if len(data) == 0: break # 针对linux系统
print('-->收到客户端的消息: ', data)
self.request.send(data.upper())#self.request为双向连接对象,相当于之前的conn
except ConnectionResetError:
break
self.request.close()
if __name__ == '__main__':
server=socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyTCPhanler)
server.serve_forever() # 链接循环
客户端:(客户端不用变)
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))
# 通信循环
while True:
client.send('hello'.encode('utf-8'))
data=client.recv(1024)
print(data)
client.close()
基于UDP通信实现并发示例
服务端:
import socketserver
class MyUdphandler(socketserver.BaseRequestHandler):
def handle(self):
data,sock=self.request
sock.sendto(data.upper(),self.client_address)
if __name__ == '__main__':
server=socketserver.ThreadingUDPServer(('127.0.0.1',8081),MyUdphandler)
server.serve_forever()
客户端:(还是不变)
from socket import *
client=socket(AF_INET,SOCK_DGRAM)
while True:
client.sendto(b'hello',('127.0.0.1',8081))
data,server_addr=client.recvfrom(1024)
print(data)
3.进程理论
进程指的是一个正在进行/运行的程序,进程是用来描述程序执行过程的虚拟概念
进程vs程序
程序:一堆代码
进程:程序的执行的过程
进程的概念起源于操作系统,进程是操作系统最核心的概念,操作系统其它所有的概念都是围绕进程来
操作系统理论:
1. 操作系统是什么?
操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的一段控制程序
有两大功能:
1. 将复杂的硬件操作封装成简单的接口给应用程序或者用户去使用
2. 将多个进程对硬件的竞争变得有序
操作系统发展史
并发: 多个任务看起来是同时运行的
串行:一个任务完完整整地运行完毕,才能运行下一个任务
多道技术:(复用=>共享/共用)
1. 空间上的复用:多个任务复用内存空间
2. 时间上的复用:多个任务复用cpu的时间
1. 一个任务占用cpu时间过长会被操作系统强行剥夺走cpu的执行权限:比起串行执行反而会降低效率
2. 一个任务遇到io操作也会被操作系统强行剥夺走cpu的执行权限:比起串行执行可以提升效率