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

java socket 问题

  •  
  •   phttc · 2016-09-09 10:03:01 +08:00 · 3541 次点击
    这是一个创建于 2996 天前的主题,其中的信息可能已经有所发展或是发生改变。

    socket 通信

    java 作客户端( java.net.Socket ), c++为服务端( libevent )

    普通的单包发送和接收都没有问题..

    但是当 java 发一个包过去, c++回复多个包的时候,,

    java 端只接收到了第一个包。。。服务端显示所有的包都正常发送,但是 java 端没收到。

    java 端的接收线程代码:

    InputStream is = mSocket.getInputStream();

    while(true){

    byte[] buffer = new byte[10240];
    
    is.read(buffer);
    
    ...
    
    ...
    

    }

    各位大大,能不能给点思路

    第 1 条附言  ·  2016-09-09 12:38:37 +08:00
    举个栗子吧。。。

    客户端 C :( askid=1;current=1;total=1;)你是谁?
    服务端 S :( askid=1;current=1;total=3;)我
    S :( askid=1;current=2;total=3;)是
    S :( askid=1;current=3;total=3;)服务器


    服务端日志显示三个包都成功发送了。但是客户端的日志里就只有( current=1;total=3;)我 这么一条。
    18 条回复    2016-09-09 13:50:20 +08:00
    binbinyouliiii
        1
    binbinyouliiii  
       2016-09-09 10:24:00 +08:00
    socket 我都快忘了,我记得我以前写的好像是阻塞,然后新开线程
    Presageee
        2
    Presageee  
       2016-09-09 10:29:52 +08:00
    有定义协议吗,一个包一个包的读,每次读定长包头,解析包体长度读包体。一次性 read(buffer)肯定不行的
    loqixh
        3
    loqixh  
       2016-09-09 10:37:17 +08:00   ❤️ 1
    粘包了,先学习 socket 原理
    phttc
        4
    phttc  
    OP
       2016-09-09 10:39:32 +08:00
    @Presageee 对的,就是自定义协议的。。协议里会写当前是第几个包,一共有几个包。。。一次 read 就读出一条协议嘛,,读第二条的时候就阻塞在 read 里了,说明输入流已经是空的了。。
    phttc
        5
    phttc  
    OP
       2016-09-09 10:41:39 +08:00
    @loqixh 不好意思,我没说清楚。。我的包指的是我自己在代码里实现的分包,自定义协议里会写当前是第几个包,一共有几个包。。。不是底层的 TCP 包。。
    hcymk2
        6
    hcymk2  
       2016-09-09 11:08:28 +08:00
    @phttc
    buffer 数组的长度?
    ovear
        7
    ovear  
       2016-09-09 11:09:29 +08:00 via Android
    flush 了么
    gamexg
        8
    gamexg  
       2016-09-09 11:16:47 +08:00
    byte[] buffer = new byte[10240];
    is.read(buffer);

    先把 buffer 打出来,应该还是拆包部分没做好。
    skydiver
        9
    skydiver  
       2016-09-09 11:22:05 +08:00 via Android   ❤️ 1
    TCP 是流协议,没有包的概念… x3

    需要的话要自己分包
    hustfox
        10
    hustfox  
       2016-09-09 11:29:40 +08:00
    一般都是在包里加长度字段,根据长度字段来收数据的。因为如果 socket 包过长的话会自动拆分成多个包的。
    loqixh
        11
    loqixh  
       2016-09-09 11:39:07 +08:00
    @phttc 这样是不行的,要用长度分割,要不就和 http 一样用符号分割,因为 socket 会缓存
    wwqgtxx
        12
    wwqgtxx  
       2016-09-09 11:40:27 +08:00
    阻塞在 read 中应该是填不满你的 10240 这么大的缓冲区,而不是没有数据
    anexplore
        13
    anexplore  
       2016-09-09 11:46:48 +08:00
    c++端数据都 flush 出来了嘛 或者你试一下 c++端发完包就 close socket
    crazyxin1988
        14
    crazyxin1988  
       2016-09-09 11:52:50 +08:00   ❤️ 1
    is.read(buffer); 这样读取方式不对。一般这样读数据:

    while((len = is.read(buffer)) != -1){

    }
    phttc
        15
    phttc  
    OP
       2016-09-09 12:40:35 +08:00
    @wwqgtxx 跟缓冲区大小没关系的。。
    @skydiver @hustfox @loqixh

    举个栗子吧。。。

    客户端 C :( askid=1;current=1;total=1;)你是谁?
    服务端 S :( askid=1;current=1;total=3;)我
    S :( askid=1;current=2;total=3;)是
    S :( askid=1;current=3;total=3;)服务器


    服务端日志显示三个包都成功发送了。但是客户端的日志里就只有( current=1;total=3;)我 这么一条。
    anexplore
        16
    anexplore  
       2016-09-09 12:56:02 +08:00   ❤️ 1
    @phttc 怎么判断的发送成功? 建议还是 抓包看一下
    21grams
        17
    21grams  
       2016-09-09 13:19:37 +08:00   ❤️ 1
    建议用 wireshark 抓一下包, server 端和 client 端都要抓,首先要保证在 tcp 层上所有的数据确实是发出来了。
    phttc
        18
    phttc  
    OP
       2016-09-09 13:50:20 +08:00
    @anexplore @21grams 谢谢,找到原因了。服务端说发送成功,其实并没有发出来。。。正在研究服务端到底是什么情况。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5453 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 952ms · UTC 03:23 · PVG 11:23 · LAX 19:23 · JFK 22:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.