2016-10-02 7 views
0

誰かが入力したときに何かを入力せずにプログラムが入力を停止するプログラムがありました。以下Python 3ソケットアプリはデータの送信を停止します

#Client 
import socket 
from time import sleep 
import time 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

host = 'localhost' 
port = 9990 

s.connect((host, port)) 

print('connecting') 

global ab 

try: 
    ab = input('enter input') 
except Exception as eb: 
    ab = 'hello' 
s.sendall(ab.encode()) 

while True: 
    global hi 
    try: 
     hi = input('enter input') 
    except Exception as b: 
     hi = input('enter input') 

    try: 
     dataNew = s.recv(4024) 
     s.sendall(hi.encode()) 

    except Exception as be: 
     print('try again') 

    if dataNew: 
     print(dataNew) 

    if not dataNew: 
     print('error') 
     break 

サーバー:

#Server 
import socket 

host = 'localhost' 
port = 9990 

try: 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except Exception as e: 
    print("Error creating socket") 

try: 
    s.bind((host, port)) 
    print('Binding socket') 
    s.listen(10) 
    print('listening') 
except Exception as e: 
    print('Error creating server') 

def mainInput(): 
    while True: 
     try: 

      dataNew = c.recv(4024) 
      c.sendall(dataNew) 
      if not dataNew: 

       print('waiting or disconnected') 
       break 

      if dataNew: 
       print(dataNew, a) 

     except Exception as b: 
      print('error') 

def mainLoop(): 
    while True: 
     global c 
     global a 
     c, a = s.accept() 
     print('Connected by', a) 
     mainInput() 

mainLoop() 

問題が空白のメッセージを入力すると、プログラムを壊すということです。

答えて

0

ここでの主な問題は、input()と呼んでいることです。しかし、ユーザーが単にenterを押すと、その関数は空の文字列を返します(inputは改行を取り除きます)。空文字列にはゼロ文字が含まれます。ソケットにゼロ文字を書き込むと、何も送られません(TCPはストリーム指向のプロトコルであり、 "メッセージ"境界を尊重しません)ので、0バイトのsendは本質的にノーオペレーションです[ただし、閉鎖状態またはシャットダウン状態にある - 例外を生成することができる)])。したがって、クライアントは何も送信せずに、サーバーからエコー応答を読み取ろうとします。しかし、サーバは何も受け取っていないので、サーバはまだrecvで待機しており、決して自身のsendallには到着しません。だから今クライアントはrecvで(永遠に)待っています。コード内

その他の問題:あなたは、サーバーのセットアップ中にエラーを検出した場合、その後の操作は、前の操作の結果に依存するため

が、あなたは、単にメッセージを印刷し続けるのではなく、終了する必要があります。

同様に、サーバで例外が発生した場合は、切断された状態でソケットを操作しようとすると例外的に例外が発生するため、ループを中断する必要があります。 recvが空の文字列を返す場合

、それは文字列が空であっても(以降、あなたがすぐにではなく、文字列のsendallを試みるよりも、ループを終了する必要がありますので、接続相手側が閉じられたことを意味する(またはshutdown)上記のように)、例外を生成する可能性があります。

関連する問題