2017-11-23 7 views
0

私は選択モジュールの機能を使用して、クライアントを扱うことができるTCP serverを実装しようとしているが、私はTCPサーバーのselect()モジュールの機能を実装する方法

  1. How does the select() function in the select module of Python exactly work?
  2. からチュートリアルで混乱しています
  3. https://pymotw.com/2/select

私が知りたい。私のコードは正しいのですか?もしそうでなければ、それをどうやって修正することができますか?

サーバ側

import socket,sys,os,select,Queue 
HOST = 'localhost'     
PORT = 3820 

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.setblocking(0) 
server.bind((HOST, PORT)) 

server.listen(5) 
inputs = [ server ] 

while (1): 
    inputready,outputready,exceptready = select.select(inputs,[],[]) 
    for s in inputready: 
     if s is server: 
      conn, addr = server.accept() 
      print 'Client connected ..' 
      conn.setblocking(0) 
      inputs.append(conn) 
     else: 
      reqCommand = conn.recv(2048) 
      if reqCommand: 
      print 'Client> %s' %(reqCommand) 

    if (reqCommand == 'quit'): 
     print 'Client disconected' 
     break 

    #list file on server 
    elif (reqCommand == 'lls'): 
     start_path = os.listdir('.') # server directory 
     for path,dirs,files in os.walk(start_path): 
      for filename in files: 
       print os.path.join(filename) 

    else: 
     string = reqCommand.split(' ', 1) #in case of 'put' and 'get' method 
     reqFile = string[1] 

     if (string[0] == 'put'): 
      with open(reqFile, 'wb') as file_to_write: 
       while True: 
        data = conn.recv(2048) 
        # print data 
        if not data: 
         break 
        # print data 
        file_to_write.write(data) 
        file_to_write.close() 
        break 
      print 'Receive Successful' 

     elif (string[0] == 'get'): 
      with open(reqFile, 'rb') as file_to_send: 
       for data in file_to_send: 
        conn.sendall(data) 
      print 'Send Successful' 

conn.close() 

server.close() 
+0

あなたはどう思いますか?それが正しいか?あなたはそれを試しましたか?それは動作しますか?たとえば、最初の接続が到着したときに 'reqCommand'の' NameError'を "検知"します。 – CristiFati

+0

各インポートを別々の行に入れます。 'if'から括弧を削除します。 'while True:'を使用します。 – Daniel

+0

https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ – jdv

答えて

1

あなたがselectを使用する場合、各要求はブロックされませんので、あなたは、非ブロッキングモードを設定すべきではありません。 selectでは出力を使用しません。あなたが何かを送ることを望むなら、出力が準備ができているかどうかをチェックしなければなりません。

プロトコルを使用していません。 recvは最大1024バイトまで受信できますが、各recvは1バイトしか読み取らないケースも処理する必要があります。したがって、reqCommandが完了したら(プロトコルによって)知る必要があります。

selectとすると、より多くのデータを受け取るにはwhile -loopsを使用しないでください。送信が完了するまで、メインループ内のブロックを読み込んで保存する必要があります。

selectの場合、for -loopsとsendallを使用してデータを送信しないでください。 selectを介してソケットに問い合わせて、データを出力する準備ができていれば、sendを使用して、値を返して、すでに送信されたバイト数を知る必要があります。

閉じた接続は処理しません。

関連する問題