Python I';我得到了TypeError:';str';不支持缓冲区接口
我正在尝试使用套接字连接到FTP服务器。我正在学习网络编程,所以我不会尝试使用ftplib。我搜索了stackoverflow的所有地方,因为有类似的问题,我尝试了解决方案堆栈用户必须提供的一切,但到目前为止没有一个有效。知道发生了什么事吗Python I';我得到了TypeError:';str';不支持缓冲区接口,python,sockets,python-3.x,Python,Sockets,Python 3.x,我正在尝试使用套接字连接到FTP服务器。我正在学习网络编程,所以我不会尝试使用ftplib。我搜索了stackoverflow的所有地方,因为有类似的问题,我尝试了解决方案堆栈用户必须提供的一切,但到目前为止没有一个有效。知道发生了什么事吗 def connect_to_target(username, password): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((target, 21))
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()
需要一个编码的字节流作为参数。所以您需要类似于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())
形式。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())
格式。用于此行
s.send('USER' + username + '\r\n').encode()
s.send('USER' + username + '\r\n'.encode())
您正在调用encode
,就像它是从s.send
返回任何内容的方法一样,这可能不是您想要的
这条线
s.send('USER' + username + '\r\n').encode()
s.send('USER' + username + '\r\n'.encode())
您只对序列中的最后一个字符串调用encode
'\r\n'.encode()
由于其中一个字符串已编码(到bytes
type),而其他字符串仍然是正常的str
类型,因此结果连接将无法工作
要使其工作,您需要创建一个整批的字符串,并对其进行编码
s.send('USER{}\r\n'.format(username).encode())
由于该行的+
运算符,将在不创建任何临时字符串的情况下执行此操作。
s.send('USER' + username + '\r\n').encode()
s.send('USER' + username + '\r\n'.encode())
您正在调用encode
,就像它是从s.send
返回任何内容的方法一样,这可能不是您想要的
这条线
s.send('USER' + username + '\r\n').encode()
s.send('USER' + username + '\r\n'.encode())
您只对序列中的最后一个字符串调用encode
'\r\n'.encode()
由于其中一个字符串已编码(到bytes
type),而其他字符串仍然是正常的str
类型,因此结果连接将无法工作
要使其工作,您需要创建一个整批的字符串,并对其进行编码
s.send('USER{}\r\n'.format(username).encode())
由于
+
运算符的原因,将不会创建任何临时字符串。可能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中的encode('USER'+username+'\r\n'.encode())只编码最后一部分'\r\n',而不是整个字符串,这就是为什么括号版本有效?可能是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中的encode('USER'+username+'\r\n'.encode())只编码最后一部分'\r\n'而不是整个字符串,这就是为什么括号版本起作用的原因?