2017-03-15 7 views
2

私のserver.pyファイルに次のコードがあります。クライアントからのデータの受信を待機しています。さらに、私はhttpライブラリを使用することはできません。唯一のソケットライブラリ:ソケットAPIを使用して基本的なHTTPサーバーを書く

def handle_client(conn, addr): 
    print ('New client from', addr) 
    x = [] 
    try: 
     while True: 
      data = conn.recv(1024) 
      decoded_data = data.decode('utf-8') 
      # if "GET/" in data.decode('utf-8'): 
      # handle_client_get(conn) 
      # else: 
      if data: 
       print(data) 
       x.append(decoded_data) 
      else: 
       print(x) 
       break 
    finally: 
     print("in close now") 
     conn.close() 

私が午前問題は、私は私だけ手動CTRL + Cたらprint(x)文を達することができるということですが、クライアントを閉じます。それ以外の場合は印刷されません。

なぜそうですか。

ANSWER

あなたが送信されたデータが正しく受信されたように、クライアントに確認応答を送信する必要があります。

接続を終了し、タイムアウトを待つことはありません。 Expect: 100-continue そして、あなたは、クライアント

+0

もう一方の側でソケットが閉じられませんでした。受信側のチャンネルがもう一方の側でシャットダウンされた後にのみ、空のrecvが得られます。 – tdelaney

+0

しかし、クライアントからデータが送信されない場合、どのように中断できますか? 接続がある限り、クライアントからデータが送信されることはありませんが、else文には到達できません。 – user3450754

+0

より良い回答を得るには、プロトコルを定義する必要があります。より多くのデータを受け取る予定の時間枠はありますか?終了したら、サーバーは接続を開いたままにしていますか? telnetやsshなどのプロトコルの中には、数分または数時間のデータがないものもありますが、接続が有効であり、データのない期間が過ぎるとデータが増えます。 – dsh

答えて

0

編集に戻って確認応答を送信する必要があります:

これは、クライアントが送信しているので、あなたが、これはHTTPサーバでのみ使用して行われるべきである言及することを今
socketライブラリでは、この問題が解決されるまでwhileブロックを削除するような、この段階でプログラムから特定の複雑な要素を削除することをお勧めします。

server.py

def handle_client(conn, addr): 
    print ('New client from', addr) 
    x = [] 
    try: 
     data = conn.recv(1024) 
     decoded_data = data.decode('utf-8') 
     if data: 
      print(data) 
      x.append(decoded_data) 
     else: 
      print(x) 
      break 
    finally: 
     print("in close now") 
     conn.close() 

オリジナル回答:

送信者側で追加\nを送信してみてバッファ何かに残っているデータを送信するために後でflush機能を使用しますlike:

sender.py

def send_data(data,sock_obj,addr): 
    sock_obj.send(data+"\n") 
    sock_obj.flush() 
+0

私はcURLを使用していますので、そのような詳細をクライアントに送信することはできません – user3450754

+0

クライアントからすべてのデータが送信されるようなwhileループは必要ありませんか? – user3450754

1

読み取るデータの量を教えてくれるプロトコルを実装する必要があります。 HTTPの場合、要求はCRLFで区切られたヘッダで始まり、それを読み取って必要な情報を得ることができます。

w3.orgには、http request protocolの説明があります。ここで実装するよりも複雑ですが、私は一度にソケットを1文字ずつ読み込み、空の\n終了行を探して要求ヘッダーを引き出す例を含めました。一度に1文字ずつ読むことで、独自のラインバッファを実装する必要はありません。

最初の行はリクエストメソッドであり、残りの行はリクエストに含まれる他のパラメータです。たとえば、POSTの場合、ソケットから読み取るデータはまだまだ多くなります。

import re 

def handle_client(conn, addr): 
    print ('New client from', addr) 
    header = [] 
    line = [] 
    try: 
     # read ascii http client header. 
     while True: 
      c = conn.recv(1) 
      # check for early termination 
      if not c: 
       return None 
      # check for end of request line 
      elif c == b"\n": 
       # make line a string to add to header 
       line = ''.join(line).decode('ascii').strip() 
       # are we at the empty line signalling end-of-header? 
       if not line: 
        break 
       header.append(line) 
       line = [] 
      # filter out \r 
      elif c == b"\r": 
       continue 

     # request is first line of header 
     request_line = header.pop(0) 
     method, uri, http_version = re.split(r" +" request_line) 

     if method.upper() == "GET": 
      # this function needs more parameters... the uri to get and the protocol 
      # version to use. 
      handle_client_get(...) 
    finally: 
     print("in close now") 
     conn.close() 
+0

さて、クライアントはいくつかのASCII文字を含むファイルを送信する投稿要求を行います。私はすべての情報を取得しますが、すべての情報を取得すると接続を終了しません。あたかもそれがより多くのデータを待っているかのようです。それが私の問題です。 – user3450754

+0

ヘッダーには、asciiなど何かを伝えるための 'Transfer-Encoding'と、読み込むバイト数を示す' Content-Length'が含まれています。しかし、すべてのものhttpのように、合併症がある可能性があります。 _4.4メッセージの長さ[ここ](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3)を参照してください。 – tdelaney

+0

これは 'Expect:100-continue'と関係があります。問題が見つかった – user3450754

関連する問題