python多线程完成udp聊天和tcp聊天服务器

上一次贴出我写的单线程聊天服务器,单线程在服务器上肯定是不能满足需求的,这一次写个多线程的框架,下回再写多进程的把

首先我们了解一下线程和进程的概念和区别问题:


1. 进程: 通俗理解一个运行起来的程序或者软件叫做进程,而线程就是执行代码的分支
1.1 每启动进程都需要向操作系统索要运行资源(内存空间),进程是操作系统资源分配的基本单位, 只有进程把资源准备好了才能让线程执行对应的代码
1.2 默认情况下一个进程会提供一个线程(主线程),线程是依附在进程里面的,没有进程就没有线程,当然进程里面可以创建多个线程

1.3 如何理解进程: 把公司理解成进程,因为公司会提供办公资源(办公电脑,办公桌椅等),真正干活的是员工,员工可以理解成是线程


2. 进程和线程的对比
2.1 进程是操作系统资源分配的基本单位,线程是cpu调度的基本单位,提示:cpu调用某个线程,那么某个线程会执行对应的代码
2.2 先有进程,再线程,线程是依附在进程里面的,没有进程就没有线程,进程索要资源以后让线程执行对应的代码
2.3 默认一个进程会有一个线程,进程里面可以创建多个线程
2.4 进程之间不共享全局变量,但是线程之间共享全局变量,但是要注意资源竞争的问题,解决办法: 互斥锁或者线程同步
2.5 多进程开发比单进程多线程开发稳定性要强,因为某一个进程挂了不会影响其它进程的运行

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连接,



猜你喜欢

转载自blog.csdn.net/feilzhang/article/details/80209579