V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
atfeel
V2EX  ›  Android

Android 如何通过 Socket 高效率发送 int 数组

  •  
  •   atfeel · 2020-05-19 16:20:01 +08:00 · 1880 次点击
    这是一个创建于 560 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Android 如何通过 Socket 高效率发送 int 数组

    发送端想把 bitmap 发送给接收端。

    接收端只需要 bitmap 的 int[]数据

    下面代码是发送端把 bitmap 转成 int[]

    int[] data = new int[width*height];

    bitmap.getPixels(data, 0, width, 0, 0, width, height);

    如何把这个 int[] data 发送给接收端。

    数据量大约是 80,0000 的长度

    Socket 不能直接发送 int[]

    我试过把 int[]转成 byte[]在发送,但是转换花的时间太长,要求在 5ms 以内

    如果我直接把 bitmap 转成 byte[]

    byte[] data = new int[width*height];

    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, data);

    这种方法会好一点,但是也要花 30ms 左右,达不到我的要求。

    如果发送的是 byte[],接收端还得转回 int[]才能用,也太耗时

    我的接收端只想要 bitmap 的 int[],谁有什么办法吗?

    19 条回复    2020-06-03 11:30:51 +08:00
    stonefeng
        1
    stonefeng   2020-05-19 16:46:37 +08:00
    如果 socket 是基于 udp 协议的话,每个数据包的最大容量是 1472 字节(包含 header ),800,000 字节的长度肯定是无法单个数据包传输过去的,可以考虑使用 redis,这边存,那边取,避免了 upd 数据包容量的限制。
    atfeel
        2
    atfeel   2020-05-19 16:51:46 +08:00
    @stonefeng 现在已经不是协议和发送失败的问题,是发送效率的问题
    rrfeng
        3
    rrfeng   2020-05-19 16:56:56 +08:00 via Android
    啥 socket ?通过网络吗?还是本机?还是局域网?

    800000bytes/5ms = 160MBps

    asAnotherJack
        4
    asAnotherJack   2020-05-19 16:57:15 +08:00
    标题问的是传输效率,正文好像说的是转换效率
    为什么要求一定控制在 5ms 呢,图片大的话转换时间变长也正常,如果是防止客户端卡顿可以把转换过程放到子线程,主线程加个 loading 框
    stonefeng
        5
    stonefeng   2020-05-19 16:57:26 +08:00
    @atfeel socket 本身是一种高效率的数据传输方式,如果你要通过 socket 传输 800,000 字节长度的数据的话,我建议你对在发送端对数据进行拆包,在接收端进行整合,但是注意 upd 协议在数据完整性上不如 tcp,要在整合时要检测数据掉包,如果数据不完整则需要有重试机制
    May725
        6
    May725   2020-05-19 18:35:10 +08:00 via iPhone
    楼主还是说下原始需求吧
    iceheart
        7
    iceheart   2020-05-19 19:35:34 +08:00 via Android
    800k/5ms = 160M 字节 /秒,
    再考虑网络波动,我判断你的需求应该是本机数据传输,否则没法实现。
    本机传输可以考虑文件映射
    wuketidai
        8
    wuketidai   2020-05-19 19:58:11 +08:00
    人家实时直播手机录屏都可以,所以无论如何都是 lz 姿势不对
    WispZhan
        9
    WispZhan   2020-05-19 19:58:55 +08:00
    我没细算,默认楼上们都是对的。

    让我想到一个笑话: 机房在美国,客户在国内, 客户要求从国内访问美国机房网络延迟控制在 30ms 以内。
    weishu
        10
    weishu   2020-05-19 20:20:15 +08:00
    用 jni 肯定可以。你这分配这么多临时内存,Android 的 gc 不行的。
    CoderGeek
        11
    CoderGeek   2020-05-19 20:23:45 +08:00
    网络?
    atfeel
        12
    atfeel   2020-05-19 21:26:15 +08:00
    @rrfeng 用 int[] data = new int[width*height];
    bitmap.getPixels(data, 0, width, 0, 0, width, height);转成 int[] 800000 仅用了 30ms,
    atfeel
        13
    atfeel   2020-05-19 21:27:25 +08:00
    @wuketidai 对路
    atfeel
        14
    atfeel   2020-05-19 21:30:23 +08:00
    @May725 原始需求就是把 int[] data 发送给接收端
    muzuiget
        15
    muzuiget   2020-05-19 21:40:45 +08:00
    明明瓶颈就是在二进制序列化,socket 本身就是二进制流,根本就不关心你发了什么数据结构。
    muzuiget
        16
    muzuiget   2020-05-19 21:45:36 +08:00
    bitmap 对象应该直接获取二进制数据的方法或者属性,可能就是一个带 IO 之类的 Stream 接口,让你直接 read/write 就完事了,给你 int[] 多半就是让你做图形变换之类,你只是发送数据,就不需要这种操作。
    march1993
        17
    march1993   2020-05-19 22:04:59 +08:00
    类似 png 这种 低频部分在前高频部分在后 让接收端可以渐进地展示清晰图不行吗。。。
    atfeel
        18
    atfeel   2020-05-19 22:06:13 +08:00
    @muzuiget 对的
    mtdhllf
        19
    mtdhllf   2020-06-03 11:30:51 +08:00
    用 netty 发,不存在不能发送 xx 对象
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2796 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:04 · PVG 20:04 · LAX 04:04 · JFK 07:04
    ♥ Do have faith in what you're doing.