0

私は、何かを入力せずに誰かが入力するたびに、プログラムが入力を停止するプログラムを持っています。

#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()

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

4

1 に答える 1

0

ここでの主な問題は、input()何かが返ってくると想定して電話をかけていることです。ただし、ユーザーが単に Enter キーを押すと、その関数は空の文字列を返します (input改行を取り除きます)。空の文字列には文字が含まれていません。ソケットにゼロ文字を書き込むと、何も送信されません (TCP はストリーム指向のプロトコルであり、「メッセージ」境界を尊重しないため、sendゼロ バイトの a は基本的にノーオペレーションです [ただし、接続が認識されている場合)クローズ状態またはシャットダウン状態であること -- 例外が引き続き生成される可能性があります])。したがって、クライアントは何も送信せず、サーバーからエコーされた応答を読み取ろうとします。しかし、サーバーは何も受信していないため、サーバーはまだ待機してrecvおり、独自のsendall. そのため、クライアントも (永久に) で待機していますrecv

コードのその他の問題:

サーバーのセットアップでエラーを検出した場合は、メッセージを出力して続行するのではなく、終了する必要があります。後続の操作は、前の操作の結果に依存するためです。

同様に、サーバーで例外が発生した場合は、続行するのではなく、ループから抜け出す必要があります。切断された状態でソケットを操作しようとすると、通常は例外が次々と発生するためです。

Ifrecvが空の文字列を返す場合、それは相手側が接続を閉じた (または) ことを意味するため、文字列に対して をshutdown試みるのではなく、すぐにループを終了する必要があります。sendall例外を生成します。

于 2016-10-03T16:18:56.407 に答える