鱼C论坛

 找回密码
 立即注册
查看: 3148|回复: 2

关于python的int类型和byte类型相互转换的问题

[复制链接]
发表于 2017-12-9 14:12:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 china25qd 于 2017-12-9 14:16 编辑

我写了一个TCP服务器
  1. import sys
  2. import socket

  3. serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. host = "127.0.0.1"
  5. port = 8088
  6. bufsize = 1024

  7. def int_to_bytes(x):
  8.     return x.to_bytes((x.bit_length() + 7) // 8, 'big')

  9. def int_from_bytes(xbytes):
  10.     return int.from_bytes(xbytes, 'big')

  11. serversocket.bind((host,port))
  12. serversocket.listen(5)

  13. print("我的地址:%s"% str(socket.gethostbyname(host)))
  14. print("端口:%s"% str(port))

  15. while True:
  16.     clientsocket,addr = serversocket.accept()
  17.     print("链接地址:%s"% str(addr))
  18.     msg = "hello client!"+"\r\n"
  19.     msglen = int_to_bytes(len(msg))
  20.     msgbyte = msglen + msg.encode('utf-8')
  21.     print(msglen)
  22.     print("发送字符长度:%s"%str(int_from_bytes(msglen)))
  23.     print("校验长度:%s"%str(len(msgbyte)))
  24.     clientsocket.send(chr(len(msgbyte)).encode()+msgbyte)
  25.     clientmsg = clientsocket.recv(bufsize)
  26.     data = ''
  27.     data = str(clientmsg[4:len(clientmsg)],encoding="utf-8")
  28.     print("客户端发来校验值:%s"%str(int_from_bytes(clientmsg[0:1])))
  29.     print("客户端发来字长:%s"%str(int_from_bytes(clientmsg[2:3])))
  30.     print("客户端说:%s"% data)
  31.     clientsocket.close()
复制代码


用来和我的客户端通信(客户端是unity的,不是python)
然后问题来了,客户端发送的msg,流的前4位是校验值,格式是:总长度[长度[消息]]
每一个长度都是一个int16转化的bytes,且都占两位
而python的int转换bytes就占一位,以至于我回发的消息总是在前面被截掉两位
从原来的“hello client!”变成了“llo client!”

请问这个应该怎么办呢?
补充一下,我的客户端用的是现成的socket通信框架,如果改校验,会发生一些奇怪的崩溃,所以只能在服务器上想办法
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-12-10 04:09:28 | 显示全部楼层
本帖最后由 yjsx86 于 2017-12-11 05:08 编辑

回复其实也是一种学习也
我也是新手 看了你的问题 一天我都在百度 学到了好多东西
特别是编码方面
因为我一直在寻找py3中一个字符以2个字节来表示的方法 虽然把原理弄懂了 但不是解决你的办法

我在V2EX上发过一贴求助:
我现在想达到一个效果
说具体点 我想把整数 12 转成字节 以 4 个字节保存
因为客户端 在收到字节流后 读取前 4 个字节保存为长度
我尝试了好几种转换 都是 ascii

一位叫ysc3839的同学给了我答案:
https://docs.python.org/3/library/struct.html

>>> import struct
>>> struct.pack('!i', 12)
b'\x00\x00\x00\x0c'

'!i' 的含义: '!' 代表网络字节序,因为你要跟客户端通信,所以得考虑字节序的问题;'i' 代表 int。在前面的链接里都有提到。

找对方向后我翻看了一下py3的内置函数 help(int)

发现:

def int_to_bytes(x):
    return x.to_bytes((x.bit_length() + 7) // 8, 'big')
上面的写法 只是根据传入的数字大小 动态的以多少位字节来转化
如果你需要指定字节数(4):
def int_to_bytes(x):
    return x.to_bytes(4, 'big')
当然4个字节所能表示的整数是有范围了 如果超过范围则:
OverflowError: int too big to convert
这里的big指的是字节顺序 有big和little 只要记得网络传输一般是big就好 我是说不清楚网络上有答案
字符串转字节 也有分大端小端 utf-16 和 utf-32 , utf-8 没见到有说应该就是不存在这个问题
utf-16le 小
utf-16be 大
utf-32同理

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 05:09:26 | 显示全部楼层
额 打字很困难也
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-25 12:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表