简体   繁体   English

Python错误ValueError:以10为底的int()的无效文字

[英]Python Error ValueError: invalid literal for int() with base 10 ' '

I am new to Python 3.3 and I am starting to write a little guessing game using sockets. 我是Python 3.3的新手,我开始使用套接字编写一些猜谜游戏。 However I keep getting the error ValueError: invalid literal for int() with base 10: '' 但是我不断收到错误ValueError: invalid literal for int() with base 10: ''
I can't see why I get this error in the line currentGuess = int(currentGuess) as I have a similar line earlier in my code. 我看不到为什么在currentGuess = int(currentGuess)行中出现此错误,因为我的代码前面有类似的行。 If anyone could help me I would be very grateful. 如果有人能帮助我,我将不胜感激。 Here is my server and Client code. 这是我的服务器和客户端代码。 I have looked at other solutions with similar problems but I can't get any to work for me. 我看过其他有类似问题的解决方案,但我找不到任何解决方案。

Server 服务器

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

Client 客户

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

You get that error when you try to call int on an empty string: 当您尝试在一个空字符串上调用int时,会出现该错误:

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

What this means is that when you do: 这意味着您执行以下操作时:

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

currentGuess is being set to '' . currentGuess被设置为'' That is, s.recv(1024) is returning an empty string. 也就是说, s.recv(1024)返回一个空字符串。 This only happens when the connection has closed, so it means the client has stopped sending data to the server. 这仅在连接已关闭时发生,因此这意味着客户端已停止向服务器发送数据。

Getting back an empty string from s.recv() means the other side called close or shutdown on the connection (or it was interrupted in some other way—the other side quit, or someone ripped out the Ethernet cord). s.recv()获取空字符串意味着另一端在连接上被称为closeshutdown (或者它以其他某种方式被中断-另一端退出了,或者有人拔出了以太网线)。

And looking at your server code, if you say you want 3 guesses, it will try to recv 3 times… but the client will only send once, after which it will close the connection. 再看一下服务器代码,如果您说要猜测3次,它将尝试recv 3次…但是客户端只会send一次,此后它将close连接。 Which means the next recv on the server will return an empty string, which is exactly what you're seeing. 这意味着服务器上的下一个recv将返回一个空字符串,这正是您所看到的。

To fix this, you need to send as many guesses as the other side is expecting. 要解决此问题,您需要发送对方期望的尽可能多的猜测。 Something like this: 像这样:

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

Meanwhile, although it isn't causing this particular problem, your code can't work reliably. 同时,尽管这不会引起此特定问题,但是您的代码无法可靠地工作。 Sockets are byte streams, not message streams . 套接字是字节流,而不是消息流 There is no guarantee that each send will match up with a recv on the other side. 无法保证每次send都会与对方的recv匹配。 The recv may get half of a send , or two send s bundled up together. recv可能获得send一半,或者将两个send捆绑在一起。 On some platforms, when you're using localhost, and sending small messages, and not sending things too quickly, everything just happens to work out all the time. 在某些平台上,当您使用localhost并发送小消息且发送速度不是太快时,所有事情都会一直发生。 On other platforms, things work most of the time but occasionally don't. 在其他平台上,大多数情况下都可以正常运行,但有时却无效。 On others, they fail frequently. 在其他方面,它们经常失败。

On top of that, as the docs explain, send is never guaranteed to send its entire string; 最重要的是,正如文档解释的那样, send不能保证发送其整个字符串。 that's why it returns the number of bytes actually sent. 这就是为什么它返回实际发送的字节数的原因。 You can solve this problem by just using sendall , but that won't help with the other problem. 您可以仅使用sendall来解决此问题,但这对其他问题没有帮助。

You have to build a message stream on top of the TCP byte stream, by designing and implementing a protocol. 您必须通过设计和实现协议在TCP字节流的顶部构建消息流。 That may sound scary, but a very simple protocol, "All messages end with a newline", can be implemented just by using the makefile method, like this: 这听起来可能很可怕,但是只需使用makefile方法即可实现一个非常简单的协议“所有消息都以换行符结尾”:

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

Now, each time you were doing either of these: 现在,每次您执行以下任一操作时:

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

… instead do these: …而是执行以下操作:

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

One last problem that isn't affecting you, but should be fixed: 最后一个不会影响您的问题,但应该解决:

Calling encode and decode with no argument is almost always a bad idea, especially with network bytes. 不带参数调用encodedecode几乎总是一个坏主意,尤其是对于网络字节。 You're asking Python to decode the data with whatever happens to be in sys.getdefaultencoding() . 您正在要求Python使用sys.getdefaultencoding()发生的任何事情来解码数据。 Can you be sure that the default encoding is the same on the client and server? 您可以确定客户端和服务器上的默认编码相同吗? Can you be sure that it can handle anything the user might type? 您可以确定它可以处理用户可能键入的任何内容吗? On a typical Windows machine, it may be something like 'cp1252' , meaning that if the user types a Chinese character, the client will quit with a UnicodeError , which isn't very user-friendly. 在典型的Windows计算机上,它可能类似于'cp1252' ,这意味着如果用户键入中文字符,则客户端将退出UnicodeError ,这不是非常用户友好的。 The right thing to do is to explicitly use 'utf-8' . 正确的做法是显式使用'utf-8' (Which means your protocol is now "All messages are in UTF-8, and end with a newline.") (这意味着您的协议现在为“所有消息均位于UTF-8中,并以换行符结尾。”)

If you're using makefile as suggested above, you can solve this even more easily by letting the file object do the encoding for you. 如果您按照上述建议使用makefile ,则可以通过让file对象为您进行编码来更轻松地解决此问题。 Just do this: 只要这样做:

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

Then you can leave out all the decode and encode calls. 然后,您可以省去所有的decodeencode调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ValueError:int()以10为底的无效文字:“-”(Python) - ValueError: invalid literal for int() with base 10: '-' (Python) (Python)ValueError:以10为底的int()的无效文字:&#39;&#39; - (Python) ValueError: invalid literal for int() with base 10: '' Python:ValueError:以10为底的int()的无效文字:“” - Python: ValueError: invalid literal for int() with base 10: '"' Python 3,ValueError:以10为底的int()无效文字: - Python 3, ValueError: invalid literal for int() with base 10: '' ValueError:以10为底的int()的无效文字:Python - ValueError: invalid literal for int() with base 10: Python Python ValueError:int()的基数为10的文字无效 - Python ValueError: invalid literal for int() with base 10 python:ValueError:以10为底的int()的无效文字:&#39;&#39; - python : ValueError: invalid literal for int() with base 10: ' ' Python ValueError:以 10 为基数的 int() 文字无效: - Python ValueError: invalid literal for int() with base 10: Python - ValueError:基数为10的int()的无效文字:&#39;&#39; - Python - ValueError: invalid literal for int() with base 10: '' Python 数据错误:ValueError:int() 的无效文字,基数为 10:&#39;42152129.0&#39; - Python data error: ValueError: invalid literal for int() with base 10: '42152129.0'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM