Вопрос по sockets, python – Разъем Python для нескольких клиентов

23

Поэтому я работаю над приложением для iPhone, для которого требуется сокет для работы с несколькими клиентами для онлайн-игр. Я попробовал Twisted, и с большим усилием мне не удалось получить кучу информации для отправки сразу, поэтому сейчас я собираюсь попробовать сокет.

Мой вопрос, используя приведенный ниже код, как вы могли бы подключить несколько клиентов? Я пробовал списки, но я просто не могу определить формат для этого. Как это сделать, если одновременно подключено несколько клиентов, и я могу отправить сообщение конкретному клиенту?

Спасибо!

#!/usr/bin/python           # This is server.py file

import socket               # Import socket module
s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000                # Reserve a port for your service.

print 'Server started!'
print 'Waiting for clients...'

s.bind((host, port))        # Bind to the port
s.listen(5)                 # Now wait for client connection.
c, addr = s.accept()     # Establish connection with client.
print 'Got connection from', addr
while True:
   msg = c.recv(1024)
   print addr, ' >> ', msg
   msg = raw_input('SERVER >> ')
   c.send(msg);
   #c.close()                # Close the connection
@sarnold Я бы предпочел придерживаться Python, я просто чувствую, что было бы хорошо придерживаться его. Спасибо за ваше предложение, хотя. Alec
Будет ли это как .... while: c, addr = s.accept () client_list = [] client_list.append (c, addr) Alec
@AlecK. Да, я могу понять, особенно если у вас есть другой код, написанный на Python. Каждый раз, когда я вижу документацию Twisted, меня просто поражает, насколько они сложны ... sarnold
Я знаю, что этоhuge изменить, но рассмотримRuby's EventMachine - Я обнаружил, что документацию по EventMachine значительно легче читать и понимать, чем документацию по Twisted. Недостатком Ruby является меньшая экосистема библиотечных привязок и пакетов, но она лучше, чем когда-то ... sarnold
Сделать некоторое времяc, addr = s.accept() когда клиент подключился, сохраните их в client_list, а затем запустите поток. Mayli

Ваш Ответ

5   ответов
13

accept может постоянно предоставлять новые клиентские подключения. Однако обратите внимание, что он и другие вызовы сокетов обычно блокируются. Поэтому у вас есть несколько вариантов на данный момент:

Open new threads to handle clients, while the main thread goes back to accepting new clients As above but with processes, instead of threads Use asynchronous socket frameworks like Twisted, or a plethora of others
Что касается 3-го пункта, теперь Python (начиная с 3.5) имеет встроенную поддержку «asyncio». для асинхронного программирования
0
#!/usr/bin/python
import sys
import os
import soskcet
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)         
host = socket.gethostname() 
port = 50000

try:
    s.bind((host, port))
except socket.error as msg:
    print(str(msg))
s.listen(10)
conn, addr = s.accept()  
print 'Got connection from'+addr[0]+':'+str(addr[1]))
while 1:
        msg = s.recv(1024)
        print +addr[0]+, ' >> ', msg
        msg = raw_input('SERVER >>'),host
        s.send(msg)
s.close()
1

к которым вы сможете подключить множество TCP-клиентов.

#!usr/bin/python
from thread import *
import socket
import sys

def clientthread(conn):
    buffer=""
    while True:
        data = conn.recv(8192)
        buffer+=data
        print buffer
    #conn.sendall(reply)
    conn.close()

def main():
    try:
        host = '192.168.1.3'
        port = 6666
        tot_socket = 26
        list_sock = []
        for i in range(tot_socket):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
            s.bind((host, port+i))
            s.listen(10)
            list_sock.append(s)
            print "[*] Server listening on %s %d" %(host, (port+i))

        while 1:
            for j in range(len(list_sock)):
                conn, addr = list_sock[j].accept()
                print '[*] Connected with ' + addr[0] + ':' + str(addr[1])
                start_new_thread(clientthread ,(conn,))
        s.close()

    except KeyboardInterrupt as msg:
        sys.exit(0)


if __name__ == "__main__":
    main()
21

My question is, using the code below, how would you be able to have multiple clients connected? I've tried lists, but I just can't figure out the format for that. How can this be accomplished where multiple clients are connected at once and I am able to send a message to a specific client?

Используя код, который вы дали, вы можете сделать это:

#!/usr/bin/python           # This is server.py file                                                                                                                                                                           

import socket               # Import socket module
import thread

def on_new_client(clientsocket,addr):
    while True:
        msg = clientsocket.recv(1024)
        #do some checks and if msg == someWeirdSignal: break:
        print addr, ' >> ', msg
        msg = raw_input('SERVER >> ')
        #Maybe some code to compute the last digit of PI, play game or anything else can go here and when you are done.
        clientsocket.send(msg)
    clientsocket.close()

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000                # Reserve a port for your service.

print 'Server started!'
print 'Waiting for clients...'

s.bind((host, port))        # Bind to the port
s.listen(5)                 # Now wait for client connection.

print 'Got connection from', addr
while True:
   c, addr = s.accept()     # Establish connection with client.
   thread.start_new_thread(on_new_client,(c,addr))
   #Note it's (addr,) not (addr) because second parameter is a tuple
   #Edit: (c,addr)
   #that's how you pass arguments to functions when creating new threads using thread module.
s.close()

Как упоминал Эли Бендерский, вы можете использовать процессы вместо потоков, вы также можете проверить Pythonthreading модуль или другие рамки асинхронных сокетов. Примечание: проверки оставлены для вас, чтобы реализовать, как вы хотите, и это просто базовая структура.

@hoangpx, обновил его.
Не могли бы вы проверить это еще раз. Я получил эту ошибку & quot; data = clientsocket.recv (16384) AttributeError: «tuple»; объект не имеет атрибута "recv" & quot;
5

Документация по SocketServer что сделало бы отличную отправную точку

import SocketServer

class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()

Попробуйте это из терминала, как это

$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello
HELLOConnection closed by foreign host.
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Sausage
SAUSAGEConnection closed by foreign host.

Вам, вероятно, потребуется использовать AForking или Threading Mixin тоже

Есть ли способ сохранить несколько соединений, используя это?

Похожие вопросы