Обычно разрешено только одно использование каждого адреса сокета (протокол / сетевой адрес / порт), - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть сервер, который использует поток для прослушивания новых подключений, а затем запускает один поток для каждого клиента для его обслуживания.Теперь сервер работает отлично, но когда клиент подключается, он выдает ошибку в заголовке.Я думаю, потому что и клиент, и сервер пытаются использовать один и тот же порт.Вот код сервера:

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def __init__(self, conne):
        initialization

    def handle(self):# "run"
        does something

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):

    pass


HOST = ''           # Symbolic name meaning all available interfaces
PORT = 1000        # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
n=1
while 1:
    conn, addr = s.accept()     # wait for a new connection. Get a new socket (conn) for each new connection
    print 'Connected by', addr

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) #this line gives me the error
    ip, port = server.server_address

    server_thread = threading.Thread(target=server.serve_forever)

    server_thread.setDaemon(True)
    server_thread.setName('Client '+str(n))
    server_thread.start()       # Start the new thread

    n+=1

    server.shutdown()
    server.server_close()

А вот клиент:

import socket

HOST, PORT = "localhost", 1000

data = "0"

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:

    sock.connect((HOST, PORT))
    sock.sendall(data)

    received = sock.recv(1024)

finally:
    sock.close()

print "Sent:     {}".format(data)
print "Received: {}".format(received)

1 Ответ

0 голосов
/ 01 декабря 2018

Сначала вы создаете серверный сокет и привязываете его к порту 1000. Затем, когда клиент подключается, вы получаете сокет, связанный с клиентом (conn, addr = s.accept()), который следует использовать для связи с клиентом, но вы полностью игнорируете его.Вместо этого вы создаете другой сервер, который попытался снова связать с портом 1000. Это приводит к ошибке «уже используется», как и ожидалось.

Я бы предложил вам проверить этопример потоков TcpServer и разветвления .Здесь изначально создается пользовательский класс, полученный из SocketServer.TCPServer (а не простой сокет сервера, как вы).Он внутренне зацикливается на принятии входящих клиентских подключений и для каждого вызова подключения, указанного SocketServer.BaseRequestHandler из нового потока или процесса (в случае разветвления), поэтому вам не нужно иметь дело с ними явно.Пользовательский обработчик запросов просто должен, ну, в общем, обработать запрос, возможно, в цикле, если связь с клиентом является многошаговой.

Помните, что подход «поток / процесс на клиента» плохо масштабируется на большом количествеодновременные клиентские подключения.

...