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 и другие.

Другие вопросы по тегам