上一次贴出我写的单线程聊天服务器,单线程在服务器上肯定是不能满足需求的,这一次写个多线程的框架,下回再写多进程的把
首先我们了解一下线程和进程的概念和区别问题:
1. 进程: 通俗理解一个运行起来的程序或者软件叫做进程,而线程就是执行代码的分支
1.1 每启动进程都需要向操作系统索要运行资源(内存空间),进程是操作系统资源分配的基本单位, 只有进程把资源准备好了才能让线程执行对应的代码
1.2 默认情况下一个进程会提供一个线程(主线程),线程是依附在进程里面的,没有进程就没有线程,当然进程里面可以创建多个线程
1.3 如何理解进程: 把公司理解成进程,因为公司会提供办公资源(办公电脑,办公桌椅等),真正干活的是员工,员工可以理解成是线程
2.6 多进程开发比单进程多线程开发资源要大,因为每启动一个进程都需要向操作系统索要运行资源,但是线程可以共享进程中的资源
首先贴出udp多任务聊天代码:
import threading import socket #发送数据功能 def send_msg(udp_socket, send_address): while True: send_msg = input("发送") udp_socket.sendto(send_msg.encode("utf-8"), send_address) if send_msg == "exit": break #显示数据功能 def display_msg(udp_socket): while True: recv_data, ip_port = udp_socket.recvfrom(1024) if recv_data: print(recv_data.decode("utf-8"), "接收到到信息",ip_port) if __name__ == "__main__": #创建udp套接字进行连接 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(("", 9090)) send_address = ("192.168.243.130", 9090) #创建子线程执行数据发送功能 send_msg_thread = threading.Thread(target=send_msg, args=(udp_socket, send_address)) send_msg_thread.start() #主线程执行数据接收和展示功能 display_msg(udp_socket)
执行多线程,只需要用到python里的threading模块,用threading模块里的类Thread创建一个线程,然后调用这个创建出来的对象的start()方法就可以执行他的target。
再贴出tcp多线程聊天服务器代码:
import socket import threading def recv_msg(client_socket, ip_port): while True: get_msg = client_socket.recv(1024) if get_msg: try: print(get_msg.decode("utf-8"), "消息来自", ip_port) except: print(get_msg.decode("gbk"), "消息来自", ip_port) else: print("客户端发送数据完成,并且下线了", ip_port) break client_socket.close() if __name__ == "__main__": # 创建服务器端的socket用于监听 tcp_serves_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_serves_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) tcp_serves_socket.bind(("", 8080)) tcp_serves_socket.listen(128) # 每次监听到的客户端socket进行一个线程的创建 while True: client_socket, ip_port = tcp_serves_socket.accept() print("连接上的客户端是:", ip_port) # 创建一个主线程守护的子线程来执行接收打印数据 recv_msg_thread = threading.Thread(target=recv_msg, args=(client_socket, ip_port), daemon=True) recv_msg_thread.start()
这代码也特别好理解,创建的子线程用于和来自多个客户端的tcp连接,