Broadcast Chat Server Использование сокет-сервера в Python
Я новичок в Python, и я использую socketserver
попытаться создать сервер, который передает все полученные сообщения от одного клиента всем подключенным клиентам, но сталкивается с проблемой. Я получаю следующую ошибку в конце:
Исключительная ситуация при обработке запроса от ('127.0.0.1', 14872) трассировки (последний вызов был последним): файл "C:\Users\umair\AppData\Local\Programs\Python\Python35-32\lib\socketserver.py", строка 628, в файле process_request_thread self.finish_request(request, client_address)" C: \ Users \ umair \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ socketserver.py ", строка 357, в файле finish_request self.RequestHandlerClass(request, client_address, self) Файл "C: \ Users \ umair \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ socketserver.py", строка 684, в файле инициализации self.handle() "C:\Users\umair\Desktop\socketserverthread_server.py", строка 52, в дескрипторе client.send(data) OSError: [WinError 10038] Была предпринята попытка выполнить операцию на чем-то, что не является сокетом
Мой код сервера выглядит следующим образом:
import socketserver
import threading
host = '127.0.0.1'
port = 6666
all_clients = []
class ThreadingHandler (socketserver.BaseRequestHandler):
def handle(self):
if (self.request) not in all_clients:
all_clients.append(self.request)
data = self.request.recv(1024)
print('%s writes: ' % str(self.client_address), end = " ")
print(data.decode())
for clients in all_clients:
clients.send(data)
class ThreadingServer (socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
myserv = ThreadingServer((host, port), ThreadingHandler)
t = threading.Thread(target = myserv.serve_forever)
t.setDaemon(True)
t.start()
print('The server is online')
Код клиента:
import socket
host = '127.0.0.1'
port = 6666
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
data = input('You: ')
sock.send(data.encode())
received = sock.recv(1024)
print('Received: ', received.decode())
Я запускаю два из этих клиентских кодов, чтобы проверить это. Первое сообщение от клиента не транслируется, а просто получено тем же клиентом. При отправке второго сообщения я получаю вышеупомянутую ошибку. Это проблема из-за того, что я создаю новый сокет в каждом цикле? Я должен создать сокет в цикле, потому что если я этого не сделаю, то я не могу отправлять и получать постоянно. Я думаю, что объект сокета уничтожается после запроса и ответа. Я понятия не имею, что происходит. Так что любая помощь приветствуется. Спасибо.
1 ответ
При отправке второго сообщения я получаю вышеупомянутую ошибку. Это проблема из-за того, что я создаю новый сокет в каждом цикле? … Я думаю, что объект сокета уничтожается после запроса и ответа. Я понятия не имею, что происходит.
У вас есть идея, что происходит; действительно объект сокета клиента sock
из предыдущего цикла цикла уничтожается в тот момент, когда новый сокет назначается переменной, что приводит к закрытию старого сокета. Но независимо от этого сервер уже закрывает свой сокет запроса из-за использования socketserver
сразу после обработки одного запроса, т.е. handle(self)
возвращается. Вышеупомянутая ошибка возникает из-за того, что этот объект закрытого сокета all_clients
во внимание, что можно сделать, например, так:
for clients in all_clients[:]:
if clients._closed: all_clients.remove(clients)
else: clients.send(data)
Первое сообщение от клиента не транслируется, а просто получено тем же клиентом.
Сообщение действительно транслируется (отправляется каждому клиенту), просто другой клиент не беспокоится о его получении, потому что он ожидает input('You: ')
,
Я должен создать сокет в цикле, потому что если я этого не сделаю, то я не могу отправлять и получать постоянно.
Это верно только в некотором смысле, потому что вы используете socketserver
, который закрывает соединение после каждого запроса - не очень полезно в случае сервера чата.
См. Вопрос " Обработка нескольких запросов с помощью select" для примера сервера без хлопот, вызванных socketserver
и другие.