问题说明
笔者是一名新入门新手,本篇文章也是给入坑新手写的,希望能给遇到此类错误的小伙伴一点提示,防止像我一样走弯路。
笔者使用的python版本为python3.6,在学习使用tftp服务端下载文件时,编写了如下的通信demo,结果报错。
from socket import *
import struct
sendData = struct.pack("!H8sb5sb",1,"test.jpg",0,"octet",0)
udpSocket = socket(AF_INET, SOCK_DGRAM)
udpSocket.sendto(sendData, ("192.168.1.32", 69))
udpSocket.close()
提示错误如下:
Traceback (most recent call last):
sendData = struct.pack("!H8sb5sb",1,x1,0,"octet",0)
struct.error: argument for 's' must be a bytes object
解决思路
首先搜索了网友的解决办法,给我提示比较多的是链接: python3中的UNICODE 与 UTF-8的简单关系.
我的理解是python3中默认的字符串为Unicode格式,而struct的函数中需要传的参数必须为“utf-8”格式,因此需要在文件开头手动声明编码格式“# coding = unf-8”
如下所示
# coding=utf-8 # 注意这里!!!!
from socket import *
import struct
s = "test.jpg"
sendData = struct.pack("!H8sb5sb",1,s.encode("utf-8"),0,"octet",0) # 这句代码中的“test.jpg”进行了编码
udpSocket = socket(AF_INET, SOCK_DGRAM)
udpSocket.sendto(sendData, ("192.168.1.32", 69))
udpSocket.close()
结果仍然是同样的错误,百思不得其解!!!!
思索良久,突然想起上段加粗的那句话
sendData = struct.pack("!H8sb5sb",1,s.encode("utf-8"),0,"octet",0)
在上面一句代码中,“octet”也需要转换格式,于是最终的正确的代码如下:
# coding=utf-8 # 注意这里!!!!
from socket import *
import struct
s = "test.jpg"
sendData = struct.pack("!H8sb5sb",1,s.encode("utf-8"),0,("octet").encode("utf-8"),0)
udpSocket = socket(AF_INET, SOCK_DGRAM)
udpSocket.sendto(sendData, ("192.168.1.32", 69))
udpSocket.close()