[英]Multiclient server in Python - how to broadcast?
I found online a simple multiclient echo server in Python using threads: 我在网上使用线程在Python中找到了一个简单的多客户端回显服务器:
#!/usr/bin/env python
import socket
import sys
import threading
class Client(threading.Thread):
def __init__(self, ip, port, connection):
threading.Thread.__init__(self)
self.connection = connection
self.ip = ip
self.port = port
def run(self):
data = self.connection.recv(1024)
if data :
self.connection.sendall(data)
else :
self.connection.close()
class Server:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.address = (self.ip, self.port)
self.server = None
self.clients = []
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(self.address)
except socket.error, e:
if self.server:
self.server.close()
sys.exit(1)
def run(self):
self.open_socket()
self.server.listen(5)
while True :
connection, (ip, port) = self.server.accept()
c = Client(ip, port, connection)
c.start()
self.clients.append(c)
self.server.close()
if __name__ == '__main__':
s = Server('127.0.0.1', 6666)
s.run()
And I wrote a client: 我写了一个客户:
import socket
import sys
port = 6666
size = 1024
s = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
s.connect(('127.0.0.1', port))
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket: " + message
sys.exit(1)
data = raw_input('> ')
s.sendall(data)
data = s.recv(size)
print "Server sent: %s " % data
s.close()
Everything works great but I wonder how could I add to the server the functionality of broadcast to be able to echo back the message to all connected clients? 一切正常,但是我不知道如何向服务器添加广播功能,以便能够将消息回显给所有连接的客户端? Or be able to send a message to a specific client?
还是能够向特定客户端发送消息?
I have all clients in server's class, but I do not know how to (and where in the server's code, in Client
class or Server
class place the code to broadcast and send private messages? Thank you. 我在服务器类中拥有所有客户端,但是我不知道如何(以及在服务器代码中的
Client
类或Server
类中的何处放置代码以广播和发送私人消息?谢谢。
EDIT: 编辑:
New server: 新服务器:
#!/usr/bin/env python
import socket
import sys
import threading
class Client(threading.Thread):
def __init__(self, ip, port, connection):
threading.Thread.__init__(self)
self.connection = connection
self.ip = ip
self.port = port
def run(self):
while True:
data = self.connection.recv(1024)
if data :
self.connection.sendall(data)
else :
break
self.connection.close()
class Server:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.address = (self.ip, self.port)
self.server = None
self.clients = []
def send_to_all_clients(self, msg):
for client in self.clients :
client.connection.send(msg)
def send_to_client(self, ip, port, msg):
for client in self.clients :
if client.ip == ip and client.port == port :
client.connection.send(msg)
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(self.address)
except socket.error, e:
if self.server:
self.server.close()
sys.exit(1)
def run(self):
self.open_socket()
self.server.listen(5)
while True :
connection, (ip, port) = self.server.accept()
c = Client(ip, port, connection)
c.start()
self.clients.append(c)
self.server.close()
if __name__ == '__main__':
s = Server('127.0.0.1', 6666)
s.run()
New client: 新客户:
import socket
import sys
port = 6666
size = 1024
s = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
s.connect(('127.0.0.1', port))
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket: " + message
sys.exit(1)
while True:
data = raw_input('> ')
s.sendall(data)
data = s.recv(size)
print "Server sent: %s " % data
s.close()
Since you already have a list of clients in your Server
, you could use it in a function like that : 由于
Server
已经有一个客户端列表,因此可以在类似以下功能中使用它:
def send_to_all_clients(self, msg):
for client in self.clients :
client.connection.send(msg)
Then you can make a function to select a specific client : 然后,您可以创建一个函数来选择特定的客户端:
def send_to_client(self, ip, port, msg):
for client in self.clients :
if client.ip == ip and client.port == port :
client.connection.send(msg)
Note 注意
It's best to add a Send()
method to Client
and call it to send the msg
instead of using client.connection.send(msg)
最好向
Client
添加Send()
方法并调用它以发送msg
而不要使用client.connection.send(msg)
You could use those functions in the server's run
method , if you modify it to handle events ( you could do that with select.select()
, or with user input ( KeyboardInterrupt
) , etc , the design is up to you ) . 您可以在服务器的
run
方法中使用这些功能,如果您对其进行修改以处理事件(可以使用select.select()
或用户输入( KeyboardInterrupt
)等来完成,则设计由您决定)。
Also you should modify both client.py and Client
, and make them more persistent , because now they close
as soon as they sendall
or recv
. 另外,您应该同时修改client.py和
Client
,并使它们更具持久性,因为现在它们一经sendall
或recv
就close
。
I hope this gives you some ideas 我希望这能给你一些想法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.