Python错误ValueError:int()的基数为10的无效文字''

时间:2013-10-23 20:24:41

标签: python

我是Python 3.3的新手,我开始用套接字写一个小猜谜游戏。但是我一直收到错误ValueError: invalid literal for int() with base 10: ''
我无法理解为什么我在行currentGuess = int(currentGuess)中出现此错误,因为我在代码中有一个类似的行。如果有人能帮助我,我将非常感激。这是我的服务器和客户端代码。我已经看过其他类似问题的解决方案,但我无法为我工作。

服务器

    #!/usr/bin/python
    import random
    import sys
    import math
    import  socket

    l = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    l.bind(("127.0.0.1", 4007))
    l.listen(5)
    print("Waiting...")
    while True:
          (s,  ca) = l.accept()
          print("Connection  from",  ca)

          #Name
          s.send("What is your name?". encode())
          names = s.recv(1024).decode()
          #Guesses

          s.send("How many guesses would you like?".encode())
          guesses = s.recv(1024).decode()
          guesses = int(guesses)
          #Random Number

          correctNumber = random.randrange(0,10)
          print(correctNumber)

          #Make Guesses
          count = 0
          while count < guesses:
                s.send("Take a Guess".encode())
                currentGuess = s.recv(1024).decode()
                currentGuess = int(currentGuess)
                if currentGuess == correctNumber:
                   s.send("You WIN".encode())
                if currentGuess != correctNumber:
                   s.send("Incorrect, Try Again ".encode())
                   count = count + 1

    s.close()

客户端

    #!/usr/bin/python
    import random
    import sys
    import math
    import socket

    s = socket.socket(socket.AF_INET,   
    socket.SOCK_STREAM)
    s.connect(("127.0.0.1", 4007))
    print("Wlcome to the numer guessing game")

    #Name
    print(s.recv(1024).decode())
    name = sys.stdin.readline()
    s.send(name.encode())

    #guesses
    print(s.recv(1024).decode())
    guesses = sys.stdin.readline()
    s.send(guesses.encode())

    #Make Guesses
    print(s.recv(1024).decode())
    currentGuess = sys.stdin.readline()
    s.send(currentGuess.encode())
    print(s.recv(80).decode())
    s.close()

2 个答案:

答案 0 :(得分:1)

当您尝试在空字符串上调用int时出现错误:

>>> int("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''

这意味着当你这样做时:

currentGuess = s.recv(1024).decode()
currentGuess = int(currentGuess)

currentGuess设置为''。也就是说,s.recv(1024)返回一个空字符串。这仅在连接关闭时发生,因此这意味着客户端已停止向服务器发送数据。

答案 1 :(得分:1)

s.recv()获取一个空字符串意味着另一方在连接上调用closeshutdown(或者以其他方式中断 - 另一方退出,或某人撕掉以太网线。)

查看您的服务器代码,如果您说要进行3次猜测,则会尝试recv 3次...但客户端只会send一次,之后会close } 连接。这意味着服务器上的下一个recv将返回一个空字符串,这正是您所看到的。

要解决此问题,您需要发送与对方期望的一样多的猜测。像这样:

#Make Guesses
for i in range(int(guesses)):
    print(s.recv(1024).decode())
    currentGuess = sys.stdin.readline()
    s.send(currentGuess.encode())
    print(s.recv(80).decode())
s.close()

同时,虽然它没有引起这个特殊问题,但您的代码无法可靠地运行。 Sockets are byte streams, not message streams。我们无法保证每个send会与另一方的recv匹配。 recv可能会将send的一半或两个send捆绑在一起。在某些平台上,当你使用localhost,发送小消息,而不是发送太快的东西时,一切都恰好就会发生。在其他平台上,事情大部分时间都有效,但有时却没有。在其他方面,他们经常失败。

最重要的是,正如the docs解释的那样,send永远不会保证发送整个字符串;这就是它返回实际发送的字节数的原因。您只需使用sendall即可解决此问题,但这对其他问题没有帮助。

您必须通过设计和实现协议,在TCP字节流之上构建消息流。这可能听起来很可怕,但是一个非常简单的协议,“所有消息以换行符结尾”,只需使用makefile方法即可实现,如下所示:

s.connect(("127.0.0.1", 4007))
f = s.makefile('r+b')

现在,每次你做其中任何一个:

foo = s.recv(80)
s.send(bar)

...而是做这些:

foo = f.readline().strip()
f.write(bar + '\n')

最后一个不影响你的问题,但应该修复:

在没有参数的情况下调用encodedecode几乎总是一个坏主意,特别是对于网络字节。您要求Python使用sys.getdefaultencoding()中的任何内容对数据进行解码。你能确定客户端和服务器上的默认编码是一样的吗?你能确定它可以处理用户可能输入的任何内容吗?在典型的Windows机器上,它可能类似'cp1252',这意味着如果用户键入中文字符,客户端将退出UnicodeError,这不是非常用户友好。正确的做法是明确使用'utf-8'。 (这意味着您的协议现在是“所有邮件都是UTF-8,并以换行符结束。”)

如果您正在使用上面建议的makefile,则可以通过让文件对象为您执行编码来更轻松地解决此问题。就这样做:

f = s.makefile('r+', encoding='utf-8')

然后,您可以省略所有decodeencode来电。