12-案例:多任务udp聊天器(一)

1.实现效果

  • 原版效果:

无法实现收发信息同时进行,必须先选1发送信息,再选2接收信息

udp-talking

  • 最终效果:

发送消息的同时,可以同时接收多条信息

talking

2.程序分析

说明

  • 编写一个有2个线程的程序
  • 线程1用来接收数据然后显示
  • 线程2用来检测键盘数据然后通过udp发送数据

要求

  1. 实现上述要求
  2. 总结多任务程序的特点

改进思路

  1. 单独开子线程用于接收消息,以达到收发消息可以同时进行
  2. 接收消息要能够连续接收多次,而不是一次
  3. 设置子线程守护主线程(解决无法正常退出问题)

3.参考代码:

开辟子线程 实现发送信息的同时接收信息

import socket
import threading


# 定义发送数据的函数
def send_data(udp_socket):

    # 定义要发送的内容
    send_content = input("请输入要发送的内容:")

    # 请输入IP地址
    ipddr = input("请输入IP地址,格式为:xxx.xxx.xxx.xxx :")

    # 请输入端口号
    port = int(input("请输入端口号:"))

    # 把要发送的数据转换为 二进制
    send_data = send_content.encode("utf-8")

    # 发送数据
    udp_socket.sendto(send_data, (ipddr, port))
    # 测试


# 定义接收数据的函数
def recvData(udp_socket):

    # 接收数据
    recv_data = udp_socket.recvfrom(1024)
    # 如果数据存在,则解析数据

    # 拆包,得到内容
    msg, list_port = recv_data
    # 拆包,得到msg
    msg = msg.decode("gbk")
    # 打印内容
    print(msg, list_port)


# 定义主入口函数
def main():

    # 定义套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定服务器客户端端口
    # udp_socket.bind(("", 7878))

    # 定义子线程并且开启
    t1 = threading.Thread(target=recvData, args=(udp_socket, ))
    # 设置守护线程
    t1.setDaemon(True)
    t1.start()

    while True:

        print("-------------------")
        print("--   1、发送数据   --")
        print("--   2、退出系统   --")
        print("-------------------")
        num = int(input("请选择功能【1/2/3】:"))

        if num < 1 or num > 3:
            print("输入不合法!,请重新输入")
        else:
            if num == 1:
                # 发送数据
                send_data(udp_socket)

            if num == 2:
                print("正在退出系统...")
                print("系统已退出")
                break


if __name__ == '__main__':
    main()