zoukankan      html  css  js  c++  java
  • 基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

    基于UDP协议 的socket套接字编程

    1.UDP套接字简单示例

    1.1服务端

    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 建立一个UDP协议的服务器 
    server.bind(("127.0.0.1",8080))
    
    while True:
        data,addr = server.recvfrom(1024)
        server.sendto(data.upper(),addr)
    server.close()
    

    1.2客户端

    import socket
    
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 建立一个UDP协议的客户端
    
    while True:
        msg = input("请输入传输内容:>>").strip()
        client.sendto(msg.encode("utf8"),("127.0.0.1,8080"))
        data,addr = client.recvfrom(1024)
        print(data)
        
    client.close()
    
    - UDP是无链接的,先启动那一端都不会报错
    - UDP协议是数据报协议.发空的时候也会自带报头,因此客户端输入空,服务器也能收到
    

    2.UDP套接字无粘包问题

    2.1服务端

    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    server.bind(("127.0.0.1",8080))
    
    data,addr = server.recvfrom(1024)
    print("第一次:",data)
    data,addr = server.recvfrom(1024)
    print("第二次:",data)
    
    server.close()
    

    2.2客户端

    import socket
    
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    client.sendto("hello".encode("utf8"),("127.0.0.1",8080))
    client.sendto("word".encode("utf8"),("127.0.0.1",8080))
    
    client.close()
    
    - UDP协议一般不用于传输大数据
    - UDP套接字虽然没有粘包问题,但是不能代替TCP套接字,因为UDP协议有一个缺陷:如果数据发送途中,数据丢失,则数据就丢失了,
    而TCP协议不会有这种缺陷,因此一般UDP套接字编程只用于无关紧要的数据发送.例如qq聊天
    

    基于socketserver实现并发的socket编程

    "本质是导入socketserver库,重写handle函数,在handle函数中写入传递信息的语句"

    1.基于TCP协议

    - 基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环
    - socketserver模式中分为两大类:server类(解决链接问题)和request类(解决通信问题)
    

    1.1服务端

    import socketserver
    
    class My_socket(socketserver.BaseRequestHandler): # 必须继承括号里面的父类
        def handle(self): # 必须重写handle方法
            while True: #  这里包括以下是正常使用的之前的方法去写接收和发送数据
                try:
                    data = self.request.recv(1024)     
                except Exception:
                    continue
                if len(data) == 0: # 这一句在linux系统才可以运行
                    break
                print(data)
                self.request.send(data.upper())
    
    if __name__ == '__main__':
        s = socketserver.ThreadingTCPServer(("192.168.11.30", 8080),My_socket) # 用封装的方法创建一个TCP的服务器
        s.serve_forever() # 循环连接 封装好的方法,直接拿来使用,就是创建一个线程
    
    - 循环建立连接,每建立一个连接就会启动一个线程 + 调用MyHandler类产生一个对象,调用该对象下的handle方法,
    专门与刚刚建立好的连接做通信循环.
    

    1.2客户端

    - 因为这个封装socket就是对服务器进行创建多线程的操作,所以客户端不需要这个库去改写,只要正常的客户端就欧克啦.
    
    import socket
    
    client = socket.socket()
    client.connect(("192.168.11.30", 8080))
    while True:
        msg = input("请输入消息:").strip()
        if msg == "q":
            break
        client.send(msg.encode("utf8"))
        data = client.recv(1024)
        print(data)
    client.close()
    

    2.基于UDP协议

    2.1服务端

    import socketserver
    
    class My_Udp_server(socketserver.BaseRequestHandler):
        def handle(self):
            data = self.request[0]
            print(f"收到来自{self.client_address}的数据:{data}")
            self.request[1].sendto(data.upper(),self.client_address)  # self.request[1] 是一个对象
    
    
    if __name__ == '__main__':
        s = socketserver.ThreadingUDPServer(("192.168.11.30", 8080),My_Udp_server)  # 创建一个UDP协议的服务器
        s.serve_forever() # 循环连接,这里学的比较浅的多线程就得使用这个库中封装的这个方法
    

    2.2客户端

    import socket
    
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    while True:
        msg = input('请输入需要传递的信息:').strip()
        if msg == "q":
            break
        client.sendto(msg.encode("utf8"),("192.168.11.30", 8080))
        data = client.recvfrom(1024)
        print(data)
    client.close()
    
  • 相关阅读:
    HDU-2067-小兔的棋盘
    HDU-1861-游船出租
    C语言笔记
    P1164 小A点菜
    P1028 数的计算
    P1217 [USACO1.5]回文质数 Prime Palindromes
    P1088 火星人
    P2392 kkksc03考前临时抱佛脚
    P3799 妖梦拼木棒
    First Step (ファーストステップ)
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11493446.html
Copyright © 2011-2022 走看看