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);
}
}
}
我必须向套接字流发送动态缓冲区大小。
它工作正常,但是当我尝试发送多个大小为
大于
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);
}
}
}