码迷,mamicode.com
首页 > 其他好文 > 详细

UDP套接字通信、socketserver并发编程

时间:2021-06-25 17:25:07      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:自己   bin   except   containe   end   hand   ref   lock   thread   

UDP套接字通信、socketserver并发编程

一 基于UDP的套接字通信

1 TCP与UDP协议的对比

### 1.可靠性
#### (1) TCP协议是可靠协议
?		对方必须回复一个ack确认消息,才会将自己这端的数据从内存中删除。

#### (2) UDP是不可靠协议
?		发送一条消息就会立即删除,不管对方是否接收到。

### 2.有无链接
?		tcp有链接,udp无链接。

### 3.传输数据的效率
?		udp更高。

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

2 基于UDP的套接字基本模板

? udp是无链接的,先启动哪一端都不会报错。

2.1 udp服务端

ss = socket()   #创建一个服务器的套接字
ss.bind()       #绑定服务器套接字
inf_loop:       #服务器无限循环
    cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送)
ss.close()                         # 关闭服务器套接字

2.2 udp客户端

cs = socket()   # 创建客户套接字
comm_loop:      # 通讯循环
    cs.sendto()/cs.recvfrom()   # 对话(发送/接收)
cs.close()                      # 关闭客户套接字

3 UDP套接字简单示例

3.1 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(1)
    server.sendto(data.upper(), client_addr)

3.2 udp客户端

# 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实现并发编程

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

1 socketserver模块的两大类:

### 1.server类
	用于解决链接循环问题。

### 2.request类
	用于解决通信循环问题。

2 使用socketserver实现基于TCP的并发

2.1 TCP并发服务端

# TCP--server端------------
import socketserver


class MyRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.client_address)
        while True:
            try:
                data = self.request.recv(1024)

                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()

2.2 TCP并发客户端

# TCP--client端------------
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‘))

3 使用socketserver实现基于UDP的并发

3.1 UDP并发服务端

# UDP--server端------------
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()

3.2 UDP并发客户端

# UDP--client端------------
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‘))

4 分析总结

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

(1) self.server即套接字对象

(2) self.request即一个链接

(3) self.client_address即客户端地址

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

(1) self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象) ,
	如:(b‘adsf‘, <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=(‘127.0.0.1‘, 8080)>)

(2) self.client_address即客户端地址

UDP套接字通信、socketserver并发编程

标签:自己   bin   except   containe   end   hand   ref   lock   thread   

原文地址:https://www.cnblogs.com/chaochaofan/p/14930268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!