UDP

UDP

特点:

  1. udp 不会管客户端或者服务端是否收到,它只管发,所以不可靠.

  2. 可以发空(数据报协议,自带头)

  3. 客户端和服务端可以又一方没在线(因为不需要建立连接)

  4. 并且由于不需要建立连接所以会发生丢包,导致数据不全。

一,简单的udp

1.1简单的udp

  1. server端

    import socket
    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1',8008))
    #udp是不需要建立连接的,可以直接发送
    #udp不需要进行监听
    #剩下的部分和tcp是一样的
    data,addr= server.recvfrom(1024)
    #data 是指传送过来的数据的部分,第二个参数addr是客户地址
    print(data,addr)
    #发送数据的时候,一定要加上地址
    server.sendto(data.upper(),addr)
    
  2. client端

    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)
    #直接发送就行
    client.sendto(b'chen',('127.0.0.1',8008))
    data,addr = client.recvfrom(1024)
    print(data,addr)
    

1.2 简单通信循环

  1. server
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8008))
while True:
    data,addr = server.recvfrom(1024)
    print(data)
    server.sendto(data.upper(),addr)

2.client

import socket
client = socket.socket(type=socket.SOCK_DGRAM)
while True:
    msg = input('>>:')
    client.sendto(msg.encode('utf-8'),('127.0.0.1',8008))
    data = client.recvfrom(1024)
    print(data)

二、udp是否粘包

udp协议没有粘包问题(udp协议又叫数据报协议),可以发空,tcp不行

  1. server

    #udp协议没有粘包问题(udp协议又叫数据报协议),可以发空,tcp不行
    import socket
    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1',8003))
    # while True:
    #     data,addr = server.recvfrom(1024)
    #     print(data)
    #     server.sendto(data.upper(),addr)
    data,addr = server.recvfrom(1024)
    print(data)
    data,addr = server.recvfrom(1024)
    print(data)
    data,addr = server.recvfrom(1024)
    print(data)
    data,addr = server.recvfrom(1024)
    print(data)
    
  2. client

    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)
    client.sendto('chen'.encode('utf8'),('127.0.0.1',8003))
    client.sendto('hello'.encode('utf8'),('127.0.0.1',8003))
    client.sendto('world'.encode('utf8'),('127.0.0.1',8003))
    client.sendto(''.encode('utf8'),('127.0.0.1',8003))
    

三、socketserver多线程通信

支持多线程,在udp中又多线程的情况下会结束上一个线程

  1. server

    #使用socketserver写服务端
    #导入模块
    import socketserver
    
    #自己定义一个类,必须继承BaseRequestHandler
    class MyTcp(socketserver.BaseRequestHandler):
        #必须重写handle方法
        def handle(self):
            print(self)
            #数据
            print(self.request[0])
            print(self.request[1])
            print(type(self.request[1]))
            self.request[1].sendto('xxxx'.encode('utf-8'),self.client_address)
    
    if __name__ == '__main__':
        #实例化得到一个tcp连接的对象,Threading意思是说,只要来了请求,
        # 它自动的开线程来处理连接跟交互数据
        #第一个参数是绑定的地址,第二个参数传一个类
        server=socketserver.ThreadingUDPServer(('127.0.0.1',8008),MyTcp)
        #一直在监听
        server.serve_forever()
    
    
  2. client1

    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)
    client.sendto('chen'.encode('utf8'),('127.0.0.1',8009))
    data = client.recvfrom(1024)
    print(data)
    
  3. client2

    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)
    client.sendto('chen'.encode('utf8'),('127.0.0.1',8009))
    data = client.recvfrom(1024)
    print(data)
    
    
原文地址:https://www.cnblogs.com/SkyOceanchen/p/11502984.html