Python中的群聊

时间:2015-11-27 00:11:46

标签: python sockets python-multithreading

我正在编写一个群聊聊天代码,它由server.py和client.py组成。基本上,任何客户端发送的任何消息都对所有客户端可见。它运行正常,直到其中一个客户端关闭连接。当客户端关闭连接时,服务器无法接受新客户端。我收到以下错误:连接('127.0.0.1',11142) 例外:[WinError 10038]尝试对非事物进行操作 套接字

server.py的代码

from socket import *
import select
import sys
import threading

QUIT = False

class Server:
    def __init__(self):
        self.host = "127.0.0.1"
        self.port = 9999
        self.threads = []
        self.backlog = 10 

    def run(self):
        all_good = False
        while not all_good:
            try:
                all_good = False
                self.sock = socket(AF_INET, SOCK_STREAM)
                self.sock.bind((self.host, self.port))
                self.sock.listen(self.backlog)
                all_good= True
                print("Server started at "+self.host+":"+str(self.port))
                break
            except Exception as err:
                print('Socket connection error... ')
                self.sock.close()
        try:
            while not QUIT:
                try:
                    client, addr = self.sock.accept()
                except socket.timeout:
                    continue
                new_thread = Client(client)
                print("Connected by ", addr)
                msg = ("Connected by %s at %s" %(new_thread.name, addr)).encode()
                for each in self.threads:
                    each.client.send(msg)

                self.threads.append(new_thread)
                new_thread.start()

                for thread in self.threads:
                    if not thread.isAlive():
                        self.threads.remove(thread)
                        thread.join()
        except KeyboardInterrupt:
                print("Terminating by Ctrl+C")
        except Exception as err:
            print("Exception: %s\nClosing" %err)
        for thread in self.threads:
            thread.join()
        self.sock.close()


class Client(threading.Thread):
    def __init__(self, client):
        threading.Thread.__init__(self)
        self.client = client

    def run(self):
        global QUIT
        done = False

        while not done:
            try:
                cmd = self.client.recv(1024).decode()
                if cmd.startswith("/name"):
                    self.client.send("Enter your username: ".encode())
                    old_name = self.name
                    self.name = self.client.recv(1024).decode()
                    msg = "%s has changed his username to %s" %(old_name, self.name)
                    for each in server.threads:
                        if each != self and each.isAlive():
                            each.client.send(msg.encode())
                    self.client.send(("Your username has been changed to %s" %self.name).encode())
                elif cmd == "/quit":
                    self.client.send("exit".encode())
                    server.threads.remove(self)
                    for each in server.threads:
                            each.client.send(("%s Disconnected" %self.name).encode())
                    QUIT = True
                    done = True
                else:
                    msg = "%s===>%s" %(self.name, cmd)
                    for each in server.threads:
                        if each != self:
                            each.client.send(msg.encode())
            except Exception as e:
                print("Connection lost", e)
                self.client.close()
                done = True
                continue

        self.client.close()
        return


if __name__ == "__main__":
    server = Server()
    server.run()

    print("Terminated")

client.py的代码

from socket import *
import sys
import threading
host = "127.0.0.1"
port = 9999

class listen(threading.Thread):
    def __init__(self, client):
        threading.Thread.__init__(self)
        self.client = client
        self.setDaemon(True)

    def run(self):
        while(True):
            data = self.client.recv(1024)
            if data.decode() == "exit":
                sys.exit(1)
            print(data.decode())




if __name__ == "__main__":
    try:
        clientSocket = socket(AF_INET, SOCK_STREAM)
        clientSocket.connect((host, port))
        print("Welcome to chat!")
        print("Type your message and press 'Enter' to send.")
        print("Send '/name' command to change your username.")
        print("Send '/quit' command to quit.")
    except error as e:
            if clientSocket:
                clientSocket.close()
            print("Could not open a socket: "+ str(e))
            sys.exit(1)

    l = listen(clientSocket)
    l.start()
    message = input()
    while message!="/quit":
        #sys.stdout.flush()
        clientSocket.send(message.encode())
        #data = self.clientSocket.recv(1024)
        #data = data.decode()
        #print("Recieved: "+str(data))
        message= input()
    clientSocket.close()

0 个答案:

没有答案