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