linux+tomcat socket长链接出现java.net.SocketException: Broken pipe

时间:2022-05-24 15:58:16
      各位大神好:

     情况是这样的,我建一个socket客户后然后往服务端发送业务数据,发送数据持续10分钟的时候就出现了这个异常java.net.SocketException: Broken pipe。这个程序在Windows上能正常运行,但是移到linux下就出现该问题了。首先我发送的数据量不是很大,也就一分钟10条数据,一条数据就几KB吧,而且中间不会停顿。苦恼了N多天,今天决定把该问题贴出来请各位帮忙看看!以下为我客户端的业务代码。


public class SendSource implements Runnable {

private static KedaLogger log = KedaLogger.getLogger(SendSource.class);
private InputStream is = null;
private OutputStream os = null;
private Socket socket;

public SendSource(Socket socket) {
this.socket = socket;
}

public void run() {

VehicleMessage vehicleMessage = null;

try { 

this.socket.setSoTimeout(10000);//设置超时时间
while (true) {

if (!this.socket.isConnected() || this.socket.isClosed()) {
log.error("socket连接对象已经关闭");
socket = StratSendUnit.createDsuCon();
} else {

vehicleMessage = StratSendUnit.getBatchVehicleInfo();
if (vehicleMessage != null) {
String msgVehicle = vehicleMessage.getVehicleXml();
String bigPictureUrl = vehicleMessage.getBigPictureUrl();
String smallPictureUrl = vehicleMessage.getSmallPictureUrl();

// /获取字符串的字节数组
byte[] msgBytes = msgVehicle.getBytes("utf-8");

if (is == null || os == null) {
is = socket.getInputStream();
os = socket.getOutputStream();
}

// (1)组装报文头,并且写入输出流
os.write(getMsgHead(msgBytes.length));
// (2)组装报文长度信息,并且写入输入流
os.write(getMsgLength(msgBytes.length));
// (3)发送报文内容
os.write(msgBytes);

// 全景大图 2:前车闪光后全景图片
if (!StringUtils.isEmpty(bigPictureUrl)) {
String[] bigPicture = bigPictureUrl.split(",");
for (int i = 0; i < bigPicture.length; i++) {

String url = bigPicture[i];
byte[] imageUrlByte = url.getBytes();
// (4)FIU发送图片数据类型信息
if (i == 0) {
      os.write(ByteUtil.int2bytes(2));// 2前闪光灯后全景图片
} else {
      os.write(ByteUtil.int2bytes(11));// 11违法图片
}
// (5)发送数据长度信息
os.write(getMsgLength(imageUrlByte.length));
// (6)发送影像数据内容
os.write(imageUrlByte);

}
}
/*
* 如果涉及传入多张图片注意传输XML里面fileCount的大小 。车牌小图片3:前车车牌号码小图片
 */

if (!StringUtils.isEmpty(smallPictureUrl)) {
byte[] imageUrlByte = smallPictureUrl.getBytes();
// (4)FIU发送图片数据类型信息
os.write(ByteUtil.int2bytes(3));
// (5)发送数据长度信息
os.write(getMsgLength(imageUrlByte.length));
// (6)发送影像数据内容
os.write(imageUrlByte);
 }

os.flush();
// /跳过和丢弃此输入流中数据的 n 个字节
is.skip(is.available());

}

}

Thread.sleep(CodeValue.sendSourceRate);
}

} catch (Exception e) {
try {
this.is.close();
this.os.close();
this.socket.close();
this.is=null;
this.os=null;
this.socket=null;

} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(vehicleMessage!=null){
StratSendUnit.saveQueueSource(vehicleMessage);//异常收回该数据
}
log.error(vehicleMessage.getVehicleXml() + "DSU发送数据异常.........." + "{" + e.getStackTrace()[0] + "-->" + e.toString() + "}");
e.printStackTrace();
}
}
}



不知道是什么原因导致了该异常的方式。

6 个解决方案

#1


饿  顶顶。请路人帮忙看看撒

#2


用nio   。。

#3


如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多

看这里分析的一个例子:
http://*.com/questions/9527795/why-a-java-net-socketexception-broken-pipe-will-occur

Some port scanners work by starting to open a connection and then immediately terminating it. Your server is not programmed to deal with a connection failure because you did not code for that possibility. You will need to use a try/catch to trap that condition and recover. Also, you should probably be handing off the connection to a separate thread for processing, so your main program can continue to receive new connections (and sending them to threads to be handled).

可能需要捕捉到该异常,并进行异常恢复处理。(因为导致不同步的原因可能是不可避免的)

#4





我在异常发生的时候进行了异常捕获,然后将发送给服务器失败的数据收回然后再重新发送。在我程序的另外一个地方有进行重新连接服务器的处理。但是现在我很想知道是什么原因导致了该异常的发生。我这里的socket是使用netty来封装的服务器。

引用 3 楼 dracularking 的回复:
如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多

看这里分析的一个例子:
http://*.com/questions/9527795/why-a-java-net-socketexception-broken-pipe-will-occur

Some port scanners work by starti……

#5


感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。

修改了以前代码中的
以前写入流如下
os.write(getMsgHead(msgBytes.length));

用了NIO之后写入流如下:
ByteBuffer buffer = ByteBuffer.wrap(getMsgHead(msgBytes.length));  
socketChannel.write(buffer);  
buffer.clear();

改了以后没有出现异常了在linux下

#6


引用 5 楼 qiangcai 的回复:
感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。

修改了以前代码中的
以前写入流如下
os.write(getMsgHead(msgBytes.length));

用了NIO之后写入流如下:
ByteBuffer buffer = ByteBuffer.wrap(getMsgH……

nio可能多了些容错处理,在稳定性上要更好吧

#1


饿  顶顶。请路人帮忙看看撒

#2


用nio   。。

#3


如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多

看这里分析的一个例子:
http://*.com/questions/9527795/why-a-java-net-socketexception-broken-pipe-will-occur

Some port scanners work by starting to open a connection and then immediately terminating it. Your server is not programmed to deal with a connection failure because you did not code for that possibility. You will need to use a try/catch to trap that condition and recover. Also, you should probably be handing off the connection to a separate thread for processing, so your main program can continue to receive new connections (and sending them to threads to be handled).

可能需要捕捉到该异常,并进行异常恢复处理。(因为导致不同步的原因可能是不可避免的)

#4





我在异常发生的时候进行了异常捕获,然后将发送给服务器失败的数据收回然后再重新发送。在我程序的另外一个地方有进行重新连接服务器的处理。但是现在我很想知道是什么原因导致了该异常的发生。我这里的socket是使用netty来封装的服务器。

引用 3 楼 dracularking 的回复:
如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多

看这里分析的一个例子:
http://*.com/questions/9527795/why-a-java-net-socketexception-broken-pipe-will-occur

Some port scanners work by starti……

#5


感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。

修改了以前代码中的
以前写入流如下
os.write(getMsgHead(msgBytes.length));

用了NIO之后写入流如下:
ByteBuffer buffer = ByteBuffer.wrap(getMsgHead(msgBytes.length));  
socketChannel.write(buffer);  
buffer.clear();

改了以后没有出现异常了在linux下

#6


引用 5 楼 qiangcai 的回复:
感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。

修改了以前代码中的
以前写入流如下
os.write(getMsgHead(msgBytes.length));

用了NIO之后写入流如下:
ByteBuffer buffer = ByteBuffer.wrap(getMsgH……

nio可能多了些容错处理,在稳定性上要更好吧