2011-10-19 8 views
1

私のコマンドラインサーバー用のGUIクライアントを作成しようとしています。しかし、私は修正できないような厄介な問題に走っています。PythonソケットRecvが正しく動作しない

私は実際の問題が何であるかは、時にはコードがうまくいくように、他の時代はそれほど確信していません。私は、主な問題は、もともと私は、私は各fはファイル名の文字列だったこの

for f in files: 
     s.send(f) 

でそれに送っていた

while 1: 
    self.data = s.recv(1024) 
    if not self.data(): 
      break 
    else: 
      print self.data() 

をしようとしたことだと思います。私はそれがrecv側で出てくることを期待していたが、recvの呼び出しごとに1つのファイル名が受信されたが、recvの呼び出しでは1つのrecv呼び出しで大量のファイル名が得られた。

これは、したがって、ループは決して終了しない。

これは私が、クライアントがサーバから正しく読み取るために取得しようとして分イムで今

def get_data(self,size = 1024): 

    self.alldata = "" 
    while 1: 

     while gtk.events_pending(): 
      gtk.main_iteration() 

     self.recvdata = self.s.recv(size) 
     self.alldata += self.recvdata 
     if self.alldata.find("\r\n\r\nEOF"): 
      print "recieved end message" 
      self.rdata = self.alldata[:self.alldata.find("\r\n\r\nEOF")] 
      break 



    print "All data Recieved: " + str(len(self.rdata)) + "Bytes" 
    print "All data :\n" + self.rdata + "\n-------------------------------------------------" 

    self.infiles = self.rdata.split("-EOS-") 
    for nf in self.infiles: 
     if len(nf) > 2: 
      self.add_message(self.incomingIcon,nf) 

を持っているコードです。私は何をしたいのですか?コマンドリストが入力され、サーバーがデータを返信して各ファイルがリストストアに追加されたときです。

これはうまくいく、それ以外は1200ファイル私が別のコマンドを入力して送信しようとすると、gtkウィンドウ全体が消えてプログラムが応答しなくなります。

申し訳ありません申し訳ありませんが、私はこの問題についてより詳しく説明することはできません。

誰かがRECVコマンドを説明することができ、なぜそれがエラーを与えることが可能ならば、これは、IMクライアントに

if(commands[0] == 'list'): 
    whatpacketshouldlooklike="" 
    print "[Request] List files ", address 
    fil = list_files(path) 
    for f in fil: 
     sdata = f 
     whatpacketshouldlooklike += sdata + "-EOS-" 
     newSock.send(sdata +"-EOS-") 
     #print "sent: " + sdata 
     newSock.send("\r\n\r\nEOF") 
    whatpacketshouldlooklike += "\r\n\r\nEOF" 
    print "---------------------------------" 
    print whatpacketshouldlooklike 
    print "---------------------------------" 
+0

元の投稿に入力ミスがありますか? 'self.data = s.recv(1024)'は 'self.data()'の次の行を悪い考え方に見せます。ソケット上の 'recv'メソッドは呼び出し可能なオブジェクトafaikを返しません。 –

+2

ストーンメタルの答えは正しいです。ソケットに2つの 'send()'呼び出しを行い、それぞれが20バイトの文字列(例えばファイル名)を持っている場合、 'recv()' endは一つの 'recv()'で40バイトを得るか、 1つの 'recv()'に39バイト、次の1バイトに40バイトを渡したり、毎回1バイトを渡す必要があります。あなたが保証するのは、最終的に納品するのが非常に難しく、決して何かを納品することは決してないということです。 –

答えて

3

をデータを送信する方法であるあなたが最初の部分で持っていた問題はありませんベースのソケットが流れているということですメッセージベース。ストリームの上に重ねるメッセージ抽象化を考え出す必要があります。このようにして、パイプのもう一方の端は何が起こっているか(1つのコマンドの一部として期待されるデータの量)を知り、何が起こるかを推測しません。

+0

こんにちは、私はあなたが今何を意味しているのか理解しています。自分のプロトコルを試して書くのは楽しいテストになると思います。構造体モジュールをms4pyの示唆に従って実装してみてください – user1003967

2

抽象レイヤー(Pyro,,zeromq)を使用するか、独自のプロトコルを定義してメッセージを区別します。

たとえば、独自のプロトコルとして、メッセージの長さを各文字列の前に「ヘッダー」として送信することができます。この場合、長さをバイナリ形式に解析するには、structモジュールを使用する必要があります。このようにしたい場合はもう一度お尋ねください。しかし、上記の抽象レイヤの1つを選択することを強くお勧めします。

2

コードにはさまざまな問題があります。

send()とrecv()の間には何の関係もありません。recv(呼び出し)で返されるデータの部分を制御しないでください。あなたのケースでは、 "\ n"でコマンド文字列を終了し、サーバー上でデータを消費するために "\ n"をチェックするだけで簡単にできます。

今他の問題:あなたは()sendallを使用してくださいすることを必要とする場合

  • あなたは(それの戻りサイズを確認せずに送信を送信使用している)は、データが完全に書かれていることを保証するものではありません。
  • ブロッキングソケット(デフォルト)でrecv(1024)を使用すると、サーバーコードが1024バイトの受信を待つことがあります。フルチャンクを取得するまでメッセージを処理できません。ブロッキングソケット、および選択モジュールを含む。
関連する問題