socket+threading实现python多人局域网聊天室

socket+threading实现python多人局域网聊天室

服务端

import socket
import threading

"""
设计思路:
1.每连接一个客户,创建一个线程
2.每个线程单独接收一个客户的信息,并向所有连接的客户发送接受到的信息
3.这样就可以实现聊天室的功能
"""


# 设置服务端
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 本机IP地址
IP = '************'
# 设置端口号
port = 12345
# 绑定主机名和端口
server.bind((IP,port))
server.listen(1000)

# 用来记录聊天室内的客户
# 使用集合,确保集合里的元素唯一
customers = set()

# 向所有用户发送信息
def send_all(data,address):
    global customers
    try:
        for customer in customers:
            customer.send(data)
    except(ConnectionResetError):
        print("----------客户已下线----------")
        customers.remove(customer)



def display_msg(customer,address):
    global customers
    # 上锁,避免出现资源竞争
    lock2.acquire()
    customers.add(customer)
    lock2.release()
    while True:
        data = customer.recv(1024)
        # 判断返回值,避免出现接收完信息后仍然反复打印
        if len(data) == 0:
            break
        # 向所有用户发送信息
        send_all(data,address)

if __name__ == '__main__':
    while True:
        # 等待客户连接,阻塞式
        customer, address = server.accept()
        # 每连接一个客户创建一个线程
        recv_thread = threading.Thread(target=display_msg,args=(customer,address))
        # 设置线程守护,一但主线程结束,所有线程停止。
        recv_thread.setDaemon(True)
        # 启动线程
        recv_thread.start()

客户端

import socket
import threading

# 创建全局变量,用作两个线程间判断数据知否是自己发的依据
middle = ''

# 查询本机ip地址
def get_host_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip

def connect():
    lock = threading.Lock()
    # 创建客户端
    customer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 目标计算机IP地址
    IP = '***************'
    port = 12345
    # 连接目标计算机
    host = customer.connect((IP, port))
    return customer

def recv():
    while True:
        msg = customer.recv(1024)
        data = msg.decode("utf-8")
        if data == middle:
            continue
        print("-----------------------------")
        print(f"{data}")
        print("-----------------------------")

def send():
    global middle
    host_ip = get_host_ip()
    while True:
        data = input()
        middle = host_ip +"发送:\n"+data
        customer.send(middle.encode('utf-8'))

if __name__ == '__main__':
    customer = connect()
    t1 = threading.Thread(target=recv)
    t2 = threading.Thread(target=send)
    t1.start()
    t2.start()

你可能感兴趣的:(python进阶)