Sockets Python套接字多个客户端

Sockets Python套接字多个客户端,sockets,python-2.x,Sockets,Python 2.x,因此,我正在开发一款iPhone应用程序,它需要一个插座来处理多个在线游戏客户端。我尝试了Twisted,但付出了很大的努力,我未能立即发送一堆信息,这就是为什么我现在要尝试使用socket 我的问题是,使用下面的代码,如何连接多个客户端?我试过列表,但我就是想不出它的格式。如果同时连接多个客户机,并且我能够向特定客户机发送消息,如何实现这一点 谢谢大家! #!/usr/bin/python # This is server.py file import socket

因此,我正在开发一款iPhone应用程序,它需要一个插座来处理多个在线游戏客户端。我尝试了Twisted,但付出了很大的努力,我未能立即发送一堆信息,这就是为什么我现在要尝试使用socket

我的问题是,使用下面的代码,如何连接多个客户端?我试过列表,但我就是想不出它的格式。如果同时连接多个客户机,并且我能够向特定客户机发送消息,如何实现这一点

谢谢大家!

#!/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

accept
可以持续提供新的客户端连接。但是,请注意,它和其他套接字调用通常是阻塞的。因此,在这一点上,您有几个选择:

  • 打开新线程以处理客户机,而主线程返回接受新客户机
  • 如上所述,但使用进程,而不是线程
  • 使用异步套接字框架,如Twisted,或大量其他框架

以下是一个从

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.

根据您的问题,您可能需要使用太多的

我的问题是,使用下面的代码,如何连接多个客户端?我试过列表,但我就是想不出它的格式。如果同时连接多个客户机,并且我能够向特定客户机发送消息,如何实现这一点

使用您提供的代码,您可以执行以下操作:

#!/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()

正如Eli Bendersky提到的,您可以使用进程而不是线程,还可以检查python
threading
module或其他异步套接字框架。注意:检查是留给您实现您想要的方式的,这只是一个基本框架。

此程序将打开26个套接字,您可以在其中连接许多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()

当连接的客户机将它们存储在客户机列表中,然后启动一个线程时,请使用
c,addr=s.accept()。。。。虽然,C,ADDR= S.Access()cliclitList= []clitMyList.AppEnter(C,ADDR),我知道这是一个巨大的变化,但是考虑到,我发现EngEngEnter文档比扭曲文档更容易阅读和理解。Ruby的缺点是库绑定和包的生态系统变小了,但它比以前好了…@sarnold我宁愿坚持使用Python,我只是觉得坚持使用它会更好。谢谢你的建议。@AlecK.,是的,我能理解,特别是如果你有其他用Python编写的代码。每当我看到扭曲的文档时,我都会觉得它们把一些事情弄得多么复杂……你能再检查一遍吗。我得到了这个错误“data=clientsocket.recv(16384)AttributeError:‘tuple’对象没有属性‘recv’”。函数中
为True:
之后的
clientsocket.close()
和底部
为True:
之后的
s.close()
将永远不会被调用,由于
中没有
break
s,而True:
则是退出循环的唯一方法,因此不会捕获异常并结束线程。上下文管理器是确保套接字已关闭的更好方法。我已将您的程序改编为python3,它将出现此错误回溯(上次调用):文件“mydir\Server.py”,第29行,已打印(f“从\“{addr}\”获得连接)名称错误:名称“addr”未定义不应
导入线程
从线程导入线程读取
线程。启动新线程()
然后替换为
线程(target=on\u new\u client,args=(c,addr))
至少对于Python3?有没有一种方法可以使用这种级联方式保持多个连接的活动状态?@我不这么认为,我尝试了这种方式,因为我有多个客户端连接,并且它是随机计时的,直到第三点,Python now(3.5版以后)已经内置了对“asyncio”的支持对于异步编程,这可能会回答问题,请考虑添加解释。
#!/usr/bin/python
import sys
import os
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)         
port = 50000

try:
    s.bind((socket.gethostname() , 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()
def get_clients():
    first_run = True
    startMainMenu = False

    while True:
        if first_run:
            global done
            done = False
            Thread(target=animate, args=("Waiting For Connection",)).start()

        Client, address = objSocket.accept()
        global menuIsOn
        if menuIsOn:
            menuIsOn = False  # will stop main menu
            startMainMenu = True

        done = True

        # Get Current Directory in Client Machine
        current_client_directory = Client.recv(1024).decode("utf-8", errors="ignore")

        # beep on connection
        beep()
        print(f"{bcolors.OKBLUE}\n***** Incoming Connection *****{bcolors.OKGREEN}")
        print('* Connected to: ' + address[0] + ':' + str(address[1]))
        try:
            get_client_info(Client, first_run)
        except Exception as e:
            print("Error data received is not a json!")
            print(e)
        now = datetime.now()
        current_time = now.strftime("%D %H:%M:%S")
        print("* Current Time =", current_time)

        print("* Current Folder in Client: " + current_client_directory + bcolors.WARNING)

        connections.append(Client)

        addresses.append(address)

        if first_run:
            Thread(target=threaded_main_menu, daemon=True).start()

            first_run = False
        else:
            print(f"{bcolors.OKBLUE}* Hit Enter To Continue.{bcolors.WARNING}\n#>", end="")
        if startMainMenu == True:
            Thread(target=threaded_main_menu, daemon=True).start()
            startMainMenu = False