【问题标题】:Python sockets error TypeError: a bytes-like object is required, not 'str' with send functionPython套接字错误TypeError:需要一个类似字节的对象,而不是带有发送功能的'str'
【发布时间】:2017-07-25 12:26:58
【问题描述】:

我正在尝试创建一个程序,该程序将在本地计算机上打开一个端口并让其他人通过 netcat 连接到它。我当前的代码是。

s = socket.socket()
host = '127.0.0.1'
port = 12345
s.bind((host, port))

s.listen(5)
while True:
    c, addr = s.accept()
    print('Got connection from', addr)
    c.send('Thank you for connecting')
    c.close()

我是 Python 和套接字的新手。但是当我运行这段代码时,它将允许我使用以下命令发送一个 netcat 连接:

nc 127.0.0.1 12345

但是在我的 Python 脚本中,我收到了 c.send 的错误:

TypeError: a bytes-like object is required, not 'str'

我基本上只是想打开一个端口,允许 netcat 连接并在那台机器上拥有一个完整的 shell。

【问题讨论】:

  • 你试过编码了吗?
  • 没有。我可以注释掉 c.send 并且它会运行。你认为这个字符串需要编码吗?

标签: python python-3.x


【解决方案1】:

另一种解决方案是向文件实例引入一种可以进行显式转换的方法。

import types

def _write_str(self, ascii_str):
    self.write(ascii_str.encode('ascii'))

source_file = open("myfile.bin", "wb")
source_file.write_str = types.MethodType(_write_str, source_file)

然后您可以将其用作source_file.write_str("Hello World")

【讨论】:

    【解决方案2】:

    这个错误的原因是在Python 3中,字符串是Unicode,但是在网络上传输时,数据需要是字节。所以...一些建议:

    1. 建议使用c.sendall() 而不是c.send() 以防止可能出现的问题,即您可能没有通过一个电话发送整个消息(请参阅docs)。
    2. 对于文字,为字节字符串添加'b'c.sendall(b'Thank you for connecting')
    3. 对于变量,您需要将 Unicode 字符串编码为字节字符串(见下文)

    最佳解决方案(应同时使用 2.x 和 3.x):

    output = 'Thank you for connecting'
    c.sendall(output.encode('utf-8'))
    

    结语/背景:这在 Python 2 中不是问题,因为字符串已经是字节字符串——您的 OP 代码在该环境中可以完美运行。 Unicode 字符串在 1.6 和 2.0 版本中被添加到 Python 中,但直到 3.0 版本成为默认字符串类型时才退居次要地位。另请参阅 this similar questionthis one

    【讨论】:

    • 谢谢你。这很有帮助,也回答了我的问题。
    【解决方案3】:

    您可以将发送行更改为:

    c.send(b'Thank you for connecting')
    

    b 改为字节。

    【讨论】:

      【解决方案4】:

      您可以使用receive.decode('utf_8') 将其解码为str。

      【讨论】:

        猜你喜欢
        • 2020-07-16
        • 1970-01-01
        • 2017-08-31
        • 1970-01-01
        • 2021-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-05
        相关资源
        最近更新 更多