zoukankan      html  css  js  c++  java
  • 网络编程(四)--基于udp协议的套接字、socketserver模块

    一、UDP协议(数据报协议)

    1、何为udp协议

    不可靠传输,”报头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。

    以太网头 ip头                      udp头                            数据                                           

    2、udp协议的特点

    (1)传输数据以数据报的形式传送。因为数据以数据包的形式发送,所以没发送一次就会接收一次

    from socket import *
    
    server=socket(AF_INET,SOCK_DGRAM)
    server.bind(('127.0.0.1',8081))
    
    print(server.recvfrom(1024))
    print(server.recvfrom(1024))
    print(server.recvfrom(1024))
    
    # (b'hello', ('127.0.0.1', 56816))
    # (b'world', ('127.0.0.1', 56816))
    # (b'sdfas', ('127.0.0.1', 56816))
    服务端
    from socket import *
    
    client=socket(AF_INET,SOCK_DGRAM)
    
    client.sendto(b'hello',('127.0.0.1',8888))
    client.sendto(b'world',('127.0.0.1',8888))
    client.sendto(b'sdfas',('127.0.0.1',8888))
    客户端

    二、基于udp协议的套接字

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

    from socket import *
    
    # 1.创建套接字对象
    server = socket(AF_INET, SOCK_DGRAM)
    
    # 2.绑定服务器IP地址和端口号
    server.bind(('127.0.0.1', 8888))
    
    # 3.收发消息
    while True:
        data, cli_addr = server.recvfrom(1024)              # 收到的是数据和客户端地址
        print(data)
        server.sendto(data.upper(), cli_addr)           # 发送消息,根据客户端地址发送消息
    
    server.close()
    服务端
    from socket import *
    
    # 1.创建套接字对象
    server = socket(AF_INET, SOCK_DGRAM)
    
    # 2.发收消息
    while True:
        client.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8888))       # 根据地址发送消息
        data, ser_addr = client.recvfrom(1024)                   # 收消息,获得服务端的消息和地址
        print(data)
    客户端

    三、socketserver模块

    1、作用

    利用socketserver模块可以实现并发

    2、基于TCP协议的并发

    自定义类中:

    1. self.request  即一个套接字对象
    2. self.client_address  即客户端地址
    # 服务端
    import socketserver
    
    class MyTCPHandler(socketserver.BaseRequestHandler):
        def handle(self):
            while True:   # 通信循环
                try:
                    data = self.request.recv(1024)
                    print(data.decode('utf-8'))
                    self.request.send(data.upper())
                except ConnectionResetError:
                    break
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MyTCPHandler)
        server.serve_forever()   # 链接循环
    # 客户端
    from socket import *
    
    cli_socket = socket(AF_INET, SOCK_STREAM)
    
    cli_socket.connect(('127.0.0.1', 8888))
    
    while True:
        cli_socket.send('hello'.encode('utf-8'))
        data = cli_socket.recv(1024)
        print(data.decode('utf-8'))
    
    cli_socket.close()

    3、基于UDP协议的并发

    自定义类中:

    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即客户端地址
    # 服务端
    import socketserver
    
    class MyUDPHandler(socketserver.BaseRequestHandler):
        def handle(self):
            while True:  # 通信循环
                print(self.request) # (b'hello', <socket.socket fd=216, family=AddressFamily.AF_INET, 
    type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8888)>)
    data, sock = self.request sock.sendto(data.upper(), self.client_address) if __name__ == '__main__': server = socketserver.ThreadingUDPServer(('127.0.0.1', 8888), MyUDPHandler) server.serve_forever() # 链接循环
    #客户端
    from socket import *
    
    cli_socket = socket(AF_INET, SOCK_STREAM)
    
    while True:
        cli_socket.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8888))
        data, server_addr = cli_socket.recvfrom(1024)
        print(data.decode('utf-8'))
    
    cli_socket.close()
  • 相关阅读:
    漫谈PID——实现与调参
    匿名上位机的使用(51版)
    #if 和 #ifdef 条件编译注意
    关于HC04超声波模块测距的思考(51版)
    关于C语言文件操作
    C语言实现简易2048小游戏
    关于OELD屏显示电池电量的简易方法
    使用notepad++作为keil的外部编辑器
    2017年个人总结
    数据存入文件
  • 原文地址:https://www.cnblogs.com/zhangbingsheng/p/10458283.html
Copyright © 2011-2022 走看看