2017-04-20 3 views
0

私は、スレッド使用してオンラインPythonで簡単なマルチクライアントエコーサーバーが見つかりました: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() 

をそして、私はクライアントを書いた:

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() 

すべてが素晴らしい作品が、私は、サーバーに機能を追加することができるか疑問に思います接続されたすべてのクライアントにメッセージをエコーバックできるようにするまたは、特定のクライアントにメッセージを送信できるかどうか

私は、サーバーのクラス内のすべてのクライアントを持っているが、私は、サーバーのコードでは、ClientクラスまたはServerクラスの場所でコードがプライベートメッセージをブロードキャストして送信する方法に(と場所がわからないのですか?ありがとうございます。

EDIT:

新サーバー:

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

新しいクライアント:

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() 

答えて

3

すでにあなたのServerにクライアントのリストを持っているので、あなたがそのような機能でそれを使用することができます。

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) 


それはClientSend()メソッドを追加してを送信するためにそれを呼び出すのがベストです10代わりに、あなたがイベント を処理するために、それを修正する場合は、サーバーのrun方法でこれらの機能を使用することができclient.connection.send(msg)

を使用する(あなたはselect.select()を持つ、またはユーザー入力(KeyboardInterrupt)などでは、デザインが起動していることを行うことができますあなたへ ) 。
また、sendallまたはrecvとすぐに、となるため、client.pyとClientの両方を変更して永続化する必要があります。
私はこれがあなたにいくつかのアイデアを与えることを願っています

+0

はい、私はこのようにしたいと思います:クライアントが 'broadcast msgtext'のようなフォーマットのメッセージを送信したときにのみ、次に。しかし、サーバー側では、クライアントからのメッセージへのアクセス権がありません。データは 'Client'クラスにあり、クライアントは' Server'クラスにあります...私は質問を更新しましたが、答えは見つけられません。助けてもらえますか? –

+0

'message'属性を' Client'(例えば 'self.msg = None')に追加し、' Server'がその値をチェックするようにすることができます。つまり:self.clientsのクライアントの場合:client.msg == 'broadcast msgtext'の場合:self.send_to_all_clients(client.msg); client.msg = None'( 'None'にリセットして、同じメッセージを何度も送信しないようにしてください) –

+0

' Server.run'のwhileループを修正して 'client.msg'をチェックする必要があります。これは、 'Server.server'にタイムアウトを設定するか、ループ内で' try.select() 'を使うかのいずれかで行うことができます。 [Here](http://www.binarytides.com/python-socket-server-code-example/)には、後者の例があります。 –

関連する問題