java 套接字输出流和损坏的管道

java socket outputstream and broken pipe

我必须向套接字流发送动态缓冲区大小。 它工作正常,但是当我尝试发送多个大小为 大于 int my_buffer_size =18 * 1024; (这是一个指示值)

我收到错误(对于某些写入):

Java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)

我的代码很简单: 例如,如果我想发送一个大文件,我会使用

读取一个文件流
byte[] bs = new byte[my_buffer_size];
while (... ){ 
fileInputStream.read(bs);
byte[] myBufferToSend = new byte[sizeBuffer];
DataOutputStream out = new DataOutputStream(cclient.getoutputStream());
out.writeInt(myBufferToSend.length);
out.write(myBufferToSend);
out.flush();
}

(文件只是一个测试缓冲区大小可以可变)

SendBufferSize 为 146988。

有没有办法修复断管错误?看了一圈,其实并没有解决问题

谢谢 任何帮助表示赞赏

我用的是经典的ServerSocket serverSocket; 和 Socket cclient

'Broken pipe' 表示您已将数据写入另一端已关闭的连接。

因此问题出在另一端,而不是在这段代码中。例如,可能另一端并不真正理解您的长度字协议,或者没有正确实现它。

如果它与此代码类似,则不会,因为您忽略了 read() 返回的结果并假设它填充了缓冲区。没有指定这样做,只传输至少一个字节。

通常,DataInputStream 不支持接收大块,因为 read 方法只是委托给底层套接字输入流,并且套接字输入流不会抱怨没有读取全部.例如。在 Oracle Java 8 中,您会得到一些 2^16 字节,其余的将被忽略。因此,当您在 DataInputStream.read 返回后关闭套接字时,发送方节点观察到“管道损坏”,同时仍在尝试发送巨大块的其余部分。解决方案是窗口阅读。下面是一个 DataInputStream 子类,它正是这样做的。

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

public class HugeDataInputStream extends DataInputStream
{
    int maxBlockLength;

    public HugeDataInputStream(InputStream in)
    {
        this(in, 0x8000);
    }

    public HugeDataInputStream(InputStream in, int maxBlockLength)
    {
        super(in);
        this.maxBlockLength = maxBlockLength;
    }

    public int readHuge(byte[] block) throws IOException
    {
        int n = block.length;
        if (n > maxBlockLength)
        {
            int cr = 0;
            while (cr < n)
            {
                cr += super.read(block, cr, Math.min(n - cr, maxBlockLength));
            }
            return cr;
        }
        else
        {
            return super.read(block);
        }
    }
}