UDP不严格区分客户端和服务端,属于面向无连接的通信方式,简单但是不可靠,容易丢失数据。

客户端-发送数据

import socket

# 创建套接字对象
s = socket.socket(socket.AF_INET, socket.SOCKET_DGRAM)

# 绑定本机的端口信息
s.bind(('',8989))

# 定义发送方地址和端口
s.sendto("要发送的数据".encoding("utf-8"), ("192.168.1.1",8808))

# 关闭套接字
s.close()

服务端- 收/发数据

import socket

# 创建套接字对象
s = socket.socket(socket.AF_INET, socket.SOCKET_DGRAM)

# 绑定本机的端口信息,第一个参数写空则为本机地址
s.bind(('',8989))

# 参数表示最大接收长度
recived_data = s.recvfrom(1024)

# 第一个元素是收到的信息,第二个是来源地址
print(recived_data)

# 关闭套接字
s.close()

收到的信息如下:

(b'123', ('192.168.32.128', 60000))

简单的聊天工具

# -*- coding: utf-8 -*-
import socket


# 发送数据
def send_data(s):
    message = input("请输入要发送的内容:")
    s.sendto(message.encode("gbk"), ("192.168.32.128", 60000))


# 接收并显示数据
def recv_data(s):
    recived_data = s.recvfrom(1024)
    print(recived_data[0].decode("gbk"))


def main():
    # udp
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 给本机套套接字绑定端口,若不指定,系统自动分配
    s.bind(('', 8989))

    # 持续发送、接收
    while True:
        print("输入1:发送数据")
        print("输入2:接收数据")
        print("输入0:退出程序")
        command = input("请输入代号:")

        if command == "1":
            send_data(s)
        elif command == "2":
            recv_data(s)
        elif command == "0":
            break
        else:
            print("输入有误,请重新输入!")
    s.close()


if __name__ == '__main__':
    main()

套接字是可以同时收发信息的,但是这个程序是阻塞的,因为它在发送完之后,就必须等着接收数据,啥也干不了。

另外,这种方式的聊天机器人,系统会自动接收发到此套接字的数据,等你要接收的时候才会显示给你,这就造成了一个大大的BUG,若有人不停的给你发送数据,而你没有及时接收,那么你的电脑可能会卡死。

这其实也是UDP的缺点。