编写一个有2个线程的程序
线程1用来接收数据然后显示
线程2用来检测键盘数据然后通过udp发送数据
要求
实现上述要求
总结多任务程序的特点
参考代码:
import socket
import threading
def send_msg(udp_socket):
# 接收用户输入的数据
send_content = input("请输入您要发送的数据:")
# 对数据进行gbk编码
send_data = send_content.encode("gbk")
# 接收对方的ip地址和端口号
dest_ip = input("请输入对方的ip地址:")
dest_port = int(input("请输入对方的端口号:"))
# 发送数据
udp_socket.sendto(send_data, (dest_ip, dest_port))
def recv_msg(udp_socket):
while True:
# 接收数据 1024:表示每次接收数据的最大字节数
recv_data, ip_port = udp_socket.recvfrom(1024)
# 解码数据
recv_content = recv_data.decode("gbk")
print(recv_content, ip_port)
if __name__ == '__main__':
# 创建udpsocket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口, 提示:客户端不强制要求绑定端口
# 在同一个电脑上端口号不能重复
udp_socket.bind(("", 8080))
# 创建接收数据的线程
recv_thread = threading.Thread(target=recv_msg, args=(udp_socket,))
# 设置成为守护主线程,主线程退出后子线程直接销毁
recv_thread.setDaemon(True)
recv_thread.start()
while True:
# 接收用户的指令
option = input("请输入功能选项 1. 发送 2. 退出:")
if option == "1":
# 发送数据
send_msg(udp_socket)
elif option == "3":
break
# 关闭socket
udp_socket.close()
参考代码:
import socket
import threading
def recv_msg(service_client_socket, ip_port):
while True:
# 接收客户端的数据
recv_data = service_client_socket.recv(1024)
if recv_data:
# 解码
recv_content = recv_data.decode("gbk")
print(recv_content)
service_client_socket.send("ok,问题正在处理中....".encode("gbk"))
else:
print(ip_port, "客户端断开连接了")
break
# 终止和客户端的通信
service_client_socket.close()
if __name__ == '__main__':
# 创建tcp服务端socket
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 程序退出立即释放端口
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(("", 7891))
# 设置监听,把主动套接字改变被动套接字,只能接收客户端的连接请求
tcp_server_socket.listen(128)
# 循环接收客户端的连接请求
while True:
# 接收客户端的连接请求
service_client_socket, ip_port = tcp_server_socket.accept()
print(ip_port)
# 创建接收数据的子线程
recv_thread = threading.Thread(target=recv_msg, args=(service_client_socket, ip_port))
# 设置守护主线程,主线程退出子线程直接销毁
recv_thread.setDaemon(True)
# 启动接收数据的子线程
recv_thread.start()
# 关闭服务端socket,不接收客户端的连接请求
tcp_server_socket.close()
参考代码:
import socket
import os
import threading
import time
def download_file(service_client_socket):
# 代码执行到说明解阻塞,说明连接建立成功
file_name_data = service_client_socket.recv(1024)
# 解码数据
file_name = file_name_data.decode("gbk")
print(file_name, ip_port)
if os.path.exists(file_name):
# 文件存在
with open(file_name, "rb") as file:
# 读取文件数据
while True:
file_data = file.read(1024)
if file_data:
# 发送文件数据给客户端
service_client_socket.send(file_data)
time.sleep(1)
else:
break
else:
print("文件不存在")
# 终止和客户端服务
service_client_socket.close()
if __name__ == '__main__':
# 创建tcp服务端socket
tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置socket选项,防止程序退出端口不立即释放的问题
tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_serve_socket.bind(("", 9090))
# 设置监听,把主动套接字改成被动套接字,被动套接字只能接收客户端的连接请求,不能收发消息
tcp_serve_socket.listen(128)
# 循环接收客户端的连接请求, 提示:现在的下载是同步下载,一个用户下载完成以后另外一个用户才能下载
while True:
# 接收客户端的连接请求
service_client_socket, ip_port = tcp_serve_socket.accept()
# 开辟线程
sub_thread = threading.Thread(target=download_file, args=(service_client_socket, ))
sub_thread.start()
# 终止提供处理连接请的服务
tcp_serve_socket.close()
import socket
if __name__ == '__main__':
# 创建tcp客户端socket
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接
tcp_client_socket.connect(("192.168.199.161", 9090))
# 获取用户输入文件名
file_name = input("请输入您要下载的文件名:")
# 使用gbk进行编码
file_name_data = file_name.encode("gbk")
# 代码执行到此,说明连接建立成功
tcp_client_socket.send(file_name_data)
with open("/home/python/Desktop/" + file_name, "wb") as file:
# 循环接收服务端发送的文件二进制数据
while True:
# 获取服务端文件数据
file_data = tcp_client_socket.recv(1024)
if file_data:
# 写入到指定文件
file.write(file_data)
else:
break
# 关闭socket
tcp_client_socket.close()