【问题标题】:I'm getting TypeError: 'str' does not support the buffer interface [duplicate]我收到 TypeError:'str' 不支持缓冲区接口 [重复]
【发布时间】:2015-11-23 03:38:42
【问题描述】:

我正在尝试使用套接字连接到 FTP 服务器。我正在学习网络编程,所以我不想使用 ftplib。我已经搜索了整个stackoverflow,因为有类似的问题,并且我已经尝试了用户必须提供的所有解决方案堆栈,但到目前为止它们都没有奏效。有什么想法吗?

def connect_to_target(username, password):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target, 21))
    data = s.recv(1024).decode()
    s.send('USER' + username + '\r\n').encode()
    data = s.recv(1024).decode()
    s.send('PASS' + password + '\r\n').encode()
    data = s.recv(3).decode()
    s.send('QUIT\r\n')
    s.close()
    return data

解释器说问题出在第 13 行,即

s.send('USER' + username + '\r\n').encode(). 

我尝试了不同的变体,例如:

s.send('USER' + username + '\r\n'.encode())

当我尝试后者时,它给了我:

TypeError: Can't convert 'bytes' object to str implicitly

【问题讨论】:

  • 也许是s.send(('USER' + username + '\r\n').encode())?
  • s.send('USER{}\r\n'.format(username).encode())
  • @ace 成功了,谢谢!但我很好奇,你知道为什么 s.send(('USER' + username + '\r\n').encode()) 工作而不是 s.send('USER' + username + '\ r\n'.encode())?
  • @ace 等等,是不是 s.send('USER' + username + '\r\n'.encode()) 中的 .encode 只是编码最后一部分 '\r\n ' 而不是整个字符串,这就是括号版本起作用的原因?

标签: python sockets python-3.x


【解决方案1】:

s.send() 期望编码的字节流作为参数。所以你想要像s.send(str.encode()) 这样的东西。

当你这样做时

s.send('USER' + username + '\r\n').encode()

您没有对字符串进行编码,而是在对s.send() 的返回值进行编码。它读起来像s.send(str).encode(),这不是你想要的。

您的第二次尝试更接近我们应该拥有的,但在这种情况下,您没有考虑运算符优先级。

s.send('USER' + username + '\r\n'.encode())

这与首先执行 '\r\n'.encode(),然后将字符串 (username) 与不允许的字节对象 ('\r\n'.encode()) 连接起来相同。该表达式的形式为s.send(str2 + str.encode()),其中. 运算符的优先级高于+ 运算符,就像在数学中如何在加法之前先进行乘法一样。

您希望对 整个 字符串进行编码。你这样做的方式只对字符串的'\r\n' 部分进行编码。

所以你需要用括号括住字符串连接,以便在编码之前先执行连接。所以你需要以下内容:

s.send(('USER' + username + '\r\n').encode())
#      ^                          ^ notice the parentheses here

这就是我们之前预期的s.send(str.encode()) 形式。

【讨论】:

    【解决方案2】:

    对于这一行

    s.send('USER' + username + '\r\n').encode()
    

    您正在调用 encode,就像它是从 s.send 返回的任何内容的方法一样,这可能不是您想要的。

    对于这一行

    s.send('USER' + username + '\r\n'.encode())
    

    您只是在序列中的最后一个字符串上调用 encode

    '\r\n'.encode()
    

    生成的连接将不起作用,因为其中一个字符串已编码(到 bytes 类型),而其他字符串仍然是正常的 str 类型。

    要使其正常工作,您需要创建一个完整的字符串和encode

    s.send('USER{}\r\n'.format(username).encode())
    

    由于+ 运算符,将在不创建任何临时字符串的情况下执行此操作。

    【讨论】:

      猜你喜欢
      • 2018-04-16
      • 1970-01-01
      • 2011-07-25
      • 2014-08-09
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多