如果在局域网中TCP Socket 是非常稳定的,极少丢包。除非你的文件很大 或者请求用户量很大。
我个人觉得可能是你的 发送和接受的地方有点问题,,一个是按行发送 一个是按字节接受,不如都统一一下。

解决方案 »

  1.   

      请教如何在一个IO流里面发送多种信息呢?(发送类型 + 文件名 + 文件主体)
      接收String好办,一个String全部接下来,哪怕一篇长篇小说也就一百几十K,把第一行砍掉就好了。
      但接收文件只能用buffer循环装载,不然文件稍大一点就挂了。
      求指点,万分感谢!
      

  2.   

    那看你文件多大了。  我以前测试TCP Socket超过10M 传输 几百用户量同时跑,不过用的是Apache MINA服务器。
    你可以固定一下 
    [类型][文件名][文件大小][文件内容] 这样的格式,传输一般都用字节传输。
    也就类似这样的:
    ByteOutputStream bos = new ByteOutputStream();
    int len = -1;
    byte[]  buffer = new byte[1024];
    while((len=in.read(buffer)) != -1) {
            bos.write(buffer,0,len);
    }
    byte[] allbytes = bos.toArrayBytes();////
      

  3.   

    不需要担心使用内存太多,只要创建一个大小合适的缓冲区循环使用来发送和接收文件内容就可以。
    你的程序的问题在于没有封包和拆包的处理,TCP是基于流的,但是我们的协议还是一个包一个包的发送和接收,所以包和包之间需要能够识别出边界。
    对于你的需求来说,你可能需要考虑文件传输因为网络原因中断并在下次传输时续传而不是重新从头开始传输文件。如果有了封包拆包,你就知道上次传输到什么位置,只要再接着传输后续的文件内容就可以。
      

  4.   

    不需要担心使用内存太多,只要创建一个大小合适的缓冲区循环使用来发送和接收文件内容就可以。
    你的程序的问题在于没有封包和拆包的处理,TCP是基于流的,但是我们的协议还是一个包一个包的发送和接收,所以包和包之间需要能够识别出边界。
    对于你的需求来说,你可能需要考虑文件传输因为网络原因中断并在下次传输时续传而不是重新从头开始传输文件。如果有了封包拆包,你就知道上次传输到什么位置,只要再接着传输后续的文件内容就可以。

      按照这样的思路设计,确实就不需要考虑文件大小的问题了。只是小弟是半路出家自学的,看得有点云里雾里了,能提供一下有关封包拆包方面的资料吗?非常感谢!
      

  5.   

    TCP  丢包......    你们玩的是TCP还是UDP啊
      

  6.   

    TCP在应用层是不会丢包的,要么就直接断了。
      

  7.   

    那看你文件多大了。  我以前测试TCP Socket超过10M 传输 几百用户量同时跑,不过用的是Apache MINA服务器
      

  8.   

    不需要担心使用内存太多,只要创建一个大小合适的缓冲区循环使用来发送和接收文件内容就可以。
    你的程序的问题在于没有封包和拆包的处理,TCP是基于流的,但是我们的协议还是一个包一个包的发送和接收,所以包和包之间需要能够识别出边界。
    对于你的需求来说,你可能需要考虑文件传输因为网络原因中断并在下次传输时续传而不是重新从头开始传输文件。如果有了封包拆包,你就知道上次传输到什么位置,只要再接着传输后续的文件内容就可以。

      按照这样的思路设计,确实就不需要考虑文件大小的问题了。只是小弟是半路出家自学的,看得有点云里雾里了,能提供一下有关封包拆包方面的资料吗?非常感谢!
    封包拆包最简单也最常用的方式,就是在每个包的前面要加一个字节长度。比如说要发一个字符串,就在字符串的前面加上字符串的长度(可以是2个字节或者4个字节)。
      

  9.   

    不需要担心使用内存太多,只要创建一个大小合适的缓冲区循环使用来发送和接收文件内容就可以。
    你的程序的问题在于没有封包和拆包的处理,TCP是基于流的,但是我们的协议还是一个包一个包的发送和接收,所以包和包之间需要能够识别出边界。
    对于你的需求来说,你可能需要考虑文件传输因为网络原因中断并在下次传输时续传而不是重新从头开始传输文件。如果有了封包拆包,你就知道上次传输到什么位置,只要再接着传输后续的文件内容就可以。

      按照这样的思路设计,确实就不需要考虑文件大小的问题了。只是小弟是半路出家自学的,看得有点云里雾里了,能提供一下有关封包拆包方面的资料吗?非常感谢!
    封包拆包最简单也最常用的方式,就是在每个包的前面要加一个字节长度。比如说要发一个字符串,就在字符串的前面加上字符串的长度(可以是2个字节或者4个字节)。
      感谢提醒,找到思路了,但现在遇到了新的问题:  在第二次发送包体的时候抛出了java.net.SocketException: sendto failed: EPIPE (Broken pipe)错误,这是怎么回事呢?
      

  10.   

    请教一下如何指定2个字节或者4个字节呢?截图中我发送的包头是自然数位,超出一位数就出错了,
    第一个包长度为1,拆包正常
    发送包 : 2 : 1
    接收包 : 2 : 1第二包长度为34,拆包中指定了获取位数为1,只读取了3,4留在了包体中了,
    发送包 : Screenshot_2014-08-25-06-22-46.png : 34
    接收包 : 4@@ : 3
      

  11.   

    请教一下如何指定2个字节或者4个字节呢?截图中我发送的包头是自然数位,超出一位数就出错了,
    长度为两字节
    [
    byte[] bytes = null;
    OutputStream out = null;
    ...
    ObjectOutputStream objOutput = new ObjectOutputStream(out);
    objOutput.writeShort((short)bytes.length);长度为四字节objOutput.writeInt((int)bytes.length);
      

  12.   

    请教一下如何指定2个字节或者4个字节呢?截图中我发送的包头是自然数位,超出一位数就出错了,
    长度为两字节
    [
    byte[] bytes = null;
    OutputStream out = null;
    ...
    ObjectOutputStream objOutput = new ObjectOutputStream(out);
    objOutput.writeShort((short)bytes.length);长度为四字节objOutput.writeInt((int)bytes.length);

    我的笨办法:
    DecimalFormat formatter = new DecimalFormat(“0000”);
    问题完美解决了,感谢各位大神!
      

  13.   

    请教一下如何指定2个字节或者4个字节呢?截图中我发送的包头是自然数位,超出一位数就出错了,
    长度为两字节
    [
    byte[] bytes = null;
    OutputStream out = null;
    ...
    ObjectOutputStream objOutput = new ObjectOutputStream(out);
    objOutput.writeShort((short)bytes.length);长度为四字节objOutput.writeInt((int)bytes.length);

    我的笨办法:
    DecimalFormat formatter = new DecimalFormat(“0000”);
    问题完美解决了,感谢各位大神!
    不客气,多给点分啊。