python socket udp并发_python中UDP基于套接字编程,并发的TCP与UDP编程,TCP与UDP的差异。...

菩提本无根,明镜亦非台

基于UDP协议的套接字通信:

1.UDP是无连接的,先启动那一端都不会报错。

UDP服务端:

ss = socket() #创建一个服务器的套接字

ss.bind() #绑定服务器套接字

inf_loop: #服务器无限循环

cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送)

ss.close() # 关闭服务器套接字

UDP客户端:

cs = socket() # 创建客户套接字

comm_loop: # 通讯循环

cs.sendto()/cs.recvfrom() # 对话(发送/接收)

cs.close() # 关闭客户套接字

2.UDP套接字通信,简单示例:

UDP服务端:

from socket import *

import time

server = socket(AF_INET, SOCK_DGRAM)

server.bind(('127.0.0.1', 8080))

while True:

data, client_addr = server.recvfrom(1024)

time.sleep(10)

server.sendto(data.upper(), client_addr)

UDP客户端:

from socket import *

client = socket(AF_INET, SOCK_DGRAM)

while True:

msg = input('>>: ').strip()

client.sendto(msg.encode("utf-8"), ('127.0.0.1', 8080))

data, server_addr = client.recvfrom(1024)

print(data.decode('utf-8'))

TCP协议 VS UDP协议

1.可靠性:

tcp协议是可靠协议:

双方在通信过程中,对方必须回复一个ack确认信息,才会将自己这端的数据从内存中删除

udp协议不可靠:

双方通信过程中,发送一条消息就会立即删除,不管对方是否接收到

2.有无链接:

tcp有链接

udp无链接

3.传输数据的效率:

tcp需要互相通信 (效率低)

udp不需要互相通信(效率高)

4.粘包问题

udp协议称之为数据报协议,每次发送都是一个完整的数据报,一个发送唯一对应一个接收所以udp协议没有粘包问题

对于tcp的粘包问题请参考上一篇博客。

5.深度理解连接https://www.cnblogs.com/linhaifeng/articles/6129246.html

基于socketserver模块实现并发

了解进程:

1.进程是什么?

顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。

2.进程的概念是从哪来的?

进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一。操作系统的其他所有内容都是围绕进程的概念展开的。

实现并发:

基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环

socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

server类:

e771adc8154886839c4d5d74033f873f.png

request类:

ccfbe9c00da303e4b3038d841e79b0e8.png

继承关系:

7b6a3b6731e99029c8f37de57b39debd.png

da8f9007379dfba0b710ecf174996866.png

997c75330589382749c31d3ead85ffa9.png

TCP服务端(支持并发):

# 支持并发版本

import socketserver

class MyRequestHandler(socketserver.BaseRequestHandler):

def handle(self): # 处理通信

print(self.client_address)

while True:

try:

data = self.request.recv(1024) # self.request=>conn

if len(data) == 0: break

self.request.send(data.upper())

except Exception:

break

self.request.close()

if __name__ == '__main__':

s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyRequestHandler, bind_and_activate=True)

s.serve_forever()

TCP客户端:

from socket import *

client=socket(AF_INET,SOCK_STREAM)

client.connect(('127.0.0.1',8080))

while True:

msg=input(">>: ").strip()

if len(msg) == 0:

continue

client.send(msg.encode('utf-8'))

data=client.recv(1024)

print(data.decode('utf-8'))

UDP服务端(支持并发):

import socketserver

class MyRequestHandler(socketserver.BaseRequestHandler):

def handle(self): # 处理通信

data,server=self.request

server.sendto(data.upper(),self.client_address)

if __name__ == '__main__':

s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyRequestHandler, bind_and_activate=True)

s.serve_forever()

UDP客户端:

from socket import *

client = socket(AF_INET, SOCK_DGRAM)

while True:

msg = input('>>: ').strip()

client.sendto(msg.encode("utf-8"), ('127.0.0.1', 8080))

data, server_addr = client.recvfrom(1024)

print(data.decode('utf-8'))

自行阅读:

以下述代码为例,分析socketserver源码:

ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer)

ftpserver.serve_forever()

查找属性的顺序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer

实例化得到ftpserver,先找类ThreadingTCPServer的__init__,在TCPServer中找到,进而执行server_bind,server_active

找ftpserver下的serve_forever,在BaseServer中找到,进而执行self._handle_request_noblock(),该方法同样是在BaseServer中

执行self._handle_request_noblock()进而执行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然后执行self.process_request(request, client_address)

在ThreadingMixIn中找到process_request,开启多线程应对并发,进而执行process_request_thread,执行self.finish_request(request, client_address)

上述四部分完成了链接循环,本部分开始进入处理通讯部分,在BaseServer中找到finish_request,触发我们自己定义的类的实例化,去找__init__方法,而我们自己定义的类没有该方法,则去它的父类也就是BaseRequestHandler中找....

源码分析总结:

基于tcp的socketserver我们自己定义的类中的

self.server即套接字对象

self.request即一个链接

self.client_address即客户端地址

基于udp的socketserver我们自己定义的类中的

self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b'adsf', )

self.client_address即客户端地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值