Python 3 struct.pack():char格式需要长度为1的字节对象

时间:2015-07-22 00:31:45

标签: python python-3.x binary

我正在尝试使用Python中的APNS发送推送通知(我知道有很多库可以做到这一点,但这有教学意图)。

我开始使用此脚本(source):

def send_push(token, payload):
    # Your certificate file
    cert = 'ck.pem'

    # APNS development server
    apns_address = ('gateway.sandbox.push.apple.com', 2195)

    # Use a socket to connect to APNS over SSL
    s = socket.socket()
    sock = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, certfile=cert)
    sock.connect(apns_address)

    # Generate a notification packet
    token = binascii.unhexlify(token)
    fmt = '!cH32sH{0:d}s'.format(len(payload))
    cmd = '\x00'
    message = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
    sock.write(message)
    sock.close()

哪个有效,但Python 2.x仅支持TSL直到版本1.所以我尝试使用Python 3运行它,我收到此错误:

Traceback (most recent call last):
  File "push_notificator.py", line 52, in <module>
    send_notification(TOKEN, json.dumps(TEST_PAYLOAD))
  File "push_notificator.py", line 46, in send_push
    payload
struct.error: char format requires a bytes object of length 1

所以看来我必须将有效负载转换为二进制,但我真的输了。这是我第一次使用Python上的二进制数据。

2 个答案:

答案 0 :(得分:1)

@cdonts的答案最终帮助了我,但我认为用单独的答案代替评论可能会更干净...

@cdonts的答案:https://stackoverflow.com/a/31551978/2298002

在打包之前,我必须同时对cmdpayload进行编码。 这是我的代码解决了它...

cmd = bytes(cmd, "utf-8")
payload = bytes(payload, "utf-8")

这是一个较长的代码片段,可以在上下文中演示...

token = "<string apns token from iOS client side>"
try:
    token = binascii.unhexlify(token)
    payload = json.dumps(payload)
    fmt = "!cH32sH{0:d}s".format(len(payload))
    cmd = '\x00'

    #python3 requirement
    cmd = bytes(cmd, "utf-8")
    payload = bytes(payload, "utf-8")

    msg = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
except Exception as e: # ref:
    print(e)    

@cdonts谢谢!! (https://stackoverflow.com/a/31551978/2298002

答案 1 :(得分:0)

在Python 3.x中使用:

bytes(payload, "utf-8")

utf-8替换为必要的编码。

希望它有所帮助。