Python 3 个套接字应用程序停止发送数据

Python 3 sockets app stops sending data

我一直在使用一个程序,只要有人按回车键,但没有输入任何内容,程序就会停止接受输入。

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

问题是输入空白消息会破坏程序。

这里的主要问题是你打电话给 input() 假设你会得到一些回报。但是如果用户只是按下回车键,该函数 returns 一个空字符串(input 去除换行符)。空字符串中有零个字符。如果您向套接字写入零个字符,则不会发送任何内容(TCP 是一种面向流的协议并且不遵守 "message" 边界,因此零字节的 send 本质上是一个空操作 [尽管 - - 如果已知连接处于关闭或关闭状态——仍然会生成异常])。所以客户端什么都不发送,然后尝试从服务器读取回显的响应。但是服务器从未收到任何东西,因此服务器仍在 recv 中等待并且永远不会到达它自己的 sendall。所以现在客户也在 recv.

等待(永远)

代码中的其他问题:

如果您在服务器设置中检测到错误,您应该退出而不是打印一条消息并继续,因为后续操作取决于前面操作的结果。

同样,如果您确实在服务器中遇到异常,您应该从循环中中断而不是继续,因为如果您继续尝试在断开连接状态下对套接字进行操作,通常只会一个接一个地出现异常。

如果recv returns 为空字符串,则表示对方已关闭(或shutdown)连接,因此您应该立即退出循环,而不是尝试sendall 在字符串上,因为(即使字符串为空,如上所述)这可能会产生异常。