2012-02-21 3 views
0

私と私のクラスメイトは、学校プロジェクトのためにPythonでサーバ/クライアントモデルを作成しています。すべてのサーバスクリプトは、クライアントからの接続(localhost上で実行されている)を受け取り、それをターミナルウィンドウに表示するメッセージを受け取ります。このスクリプトは、MacBook AirでOSX10.7.3 64bitを実行していて、このコンピュータ上で動作するはずですが、私のクラスメイトのLinuxコンピュータ(Ubuntu 11.04 64bit)またはコンピュータラボLinuxコンピュータ(Ubuntu 10.04 32bit)で動作させると、 。このスクリプトでは、サーバーとクライアントの両方が非ブロッキングに設定されていますが、これは私のMac上ではうまく動作しますが、Linuxマシンでは、クライアントnr2からデータが送信されないように、クライアントnr1からいずれかを受信する前にサーバ/クライアントスクリプトはMacOSX上で円滑に実行されますが、Ubuntuでは失敗します

Pythonをマルチプラットフォーム言語にしないでください。 MacOSとUbuntuの両方で動作するように、私たちのコードを調整する最良の方法は何でしょうか?

これはやや曖昧でしたが、私は以下のサーバとクライアントスクリプトのコードを投稿しています。

私のMacはPython 2.7.1を実行し、Ubuntu 11.04はPython 2.7.1+を実行し、Ubuntu 10.04はPython 2.6.5を実行します。

私たちはソケットプログラミングの初心者であり、初心者でもあるPython(したがって、学校プロジェクトとシンプルコード=)です。誰かが簡単な方法で詳細を教えてくれれば幸いです。

まずserver.pyファイル:

import select 
import socket 
import sys 
import threading 
import client 

class Server: 
    def __init__(self): 
    self.host = 'localhost' 
    self.port = 50000 
    self.backlog = 5 
    self.size = 1024 
    self.server = None 
    self.threads = [] 

def openSocket(self): 
    try: 
     self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.server.bind((self.host, self.port)) 
     self.server.listen(5) 
     print "Listening to port " + str(self.port) + "..." 
    except socket.error, (value,message): 
     if self.server: 
      self.server.close() 
     print "Could not open socket: " + message 
     sys.exit(1) 

def run(self): 
    self.openSocket() 
    self.server.setblocking(0) 
    input = [self.server,sys.stdin] 
    running = True 
    while running: 

     inputready, outputready, exceptready = select.select(input,[],[], 0.01)    

     for s in inputready: 
      c = client.Client(self.server.accept()) 
      self.threads.append(c) 
      print "Client " + str(c.address) + " connected" 
      inputready.pop() 
     for c in self.threads: 
      try: 
       data = c.client.recv(self.size) 
       print data 
      except socket.error, (value,message): 
       continue 

    #close threads 
    self.server.close() 
    for c in self.threads: 
     c.join() 

if __name__ == "__main__": 
s = Server() 
s.run() 

その後client.pyファイル:

import select 
import socket 
import sys 
import server 
import threading 

class Client(threading.Thread): 
def __init__(self,(client,address)): 
    threading.Thread.__init__(self) 
    self.client = client 
    self.address = address 
    self.size = 1024 

def run(self): 
    self.client.connect(('localhost',50000)) 
    c.client.setblocking(0) 
    running = True 
    while running: 

     line = sys.stdin.readline() 
     if line == "exit": 
      self.client.close() 
     else: 
      self.client.sendall(line) 

    self.client.close() 

if __name__ == "__main__": 
c = Client((socket.socket(socket.AF_INET, socket.SOCK_STREAM),'localhost')) 
c.run() 

PS:ネヴァーマインドいくつかのループにインデント。コードをコピー&ペーストしたときに何かが起きました。 PPS:いずれかのコンピュータでこれを実行すると、エラーメッセージが表示されないことに注意してください。それは単に違った働きをします。事前

答えて

1

おかげで確かに、私は、非ブロッキングソケットでゼロ経験を持っているので、私は本当にそれを助けることはできません。しかし、記述した振る舞いは、あなたのコードとまったく同じように見えます。サーバーは接続要求を受け入れ、新しいClientオブジェクトを作成し、それをリストに追加してから、同じリスト内のすべてのクライアントを1つずつリッスンします。つまり、最初のクライアントがメッセージの送受信を行うことができますが、サーバーが最初のクライアントからデータを受信して​​いるため、次のクライアントは接続できません。

また、このコードは到達しません:

self.server.close() 
    for c in self.threads: 
     c.join() 

サーバが要求の受け入れを停止したことがないので。さらに、スレッドを開始するようには見えません。スレッドを作成するだけです。とにかく

、あなたはこのように、サーバーの実行機能を変更した場合、それが動作するはずです:

from threading import Thread #this line is at the top of the file, of course 

def run(self): 
    self.openSocket() 
    self.running = True #make sure to implement some code that'll actually set this variable to False! 
    while self.running: 
     c= client.Client(self.server.accept()) 
     t= Thread(target=self.listenToClient,args=[c]) 
     t.daemon= True #this makes sure to kill the thread when the main thread exits 
     self.threads.append(t) 
     t.start() 

    #close threads 
    self.server.close() 
    for c in self.threads: 
     c.join() 

def listenToClient(self, c): 
    print "Client " + str(c.address) + " connected" 
    while self.running: 
     try: 
      data = c.client.recv(self.size) 
      if data=='': #if the client disconnected 
       return 
      print data 
     except socket.error, (value,message): 
      continue 

私は完全に間違っているか、私はあなたのコードは、Mac OSX上で動作する理由見当もつかないどちらか。

P.S:Python 3を使用しないようにしてください。これはいくつかの癖が必要です。

+1

うわー!これは両方のプラットフォーム上の魅力のように今働きます!私はサーバからファイルを送信するためにこれが必要だと思うので、私はselect()コールをあなたのコードとともにserver-fileで焼いてしまったのですか、まったく間違っていますか?とにかく、ありがとう。私はあなたが私にスレッドに関する光を見せてくれたと思ったと思う。) –

+0

私は選択モジュールを使用したことがなく、ファイルも送っていない。それでお手伝いできません、申し訳ありません。 –

関連する問題