我正在尝试创建一个聊天室,最多可以包含5个客户端。一切正常,直到客户端离开然后再次加入服务器。
它给了我这个错误:异常:[WinError 10038]尝试对非套接字的操作进行操作。 闭幕 终止
服务器日志:
服务器起始于127.0.0.1:9999
连接(' 127.0.0.1',62493)
连接丢失[WinError 10054]远程主机强制关闭现有连接
通过(' 127.0.0.1',62494)连接
例外:[WinError 10038]尝试对不是套接字的事物进行操作
关闭
终止
服务器:
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")
我认为你不需要它,但我会给你客户代码,以便你了解发生了什么。
客户端:
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()