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

逆水行舟不进则退 2013-01-29 06:35:55
各位大神好:

情况是这样的,我建一个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();
}
}
}



不知道是什么原因导致了该异常的方式。
...全文
11362 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我在异常发生的时候进行了异常捕获,然后将发送给服务器失败的数据收回然后再重新发送。在我程序的另外一个地方有进行重新连接服务器的处理。但是现在我很想知道是什么原因导致了该异常的发生。我这里的socket是使用netty来封装的服务器。
引用 3 楼 dracularking 的回复:
如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多 看这里分析的一个例子: http://stackoverflow.com/questions/9527795/why-a-java-net-socketexception-broken-pipe-will-occur Some port scanners work by starti……
dracularking 2013-01-31
  • 打赏
  • 举报
回复
引用 5 楼 qiangcai 的回复:
感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。 修改了以前代码中的 以前写入流如下 os.write(getMsgHead(msgBytes.length)); 用了NIO之后写入流如下: ByteBuffer buffer = ByteBuffer.wrap(getMsgH……
nio可能多了些容错处理,在稳定性上要更好吧
  • 打赏
  • 举报
回复
感谢前面两位仁兄的大力支持,该问题解决了。现在我采用nio来做客户端发送数据,在linux下跑了几个小时视乎没有出现该异常了。 修改了以前代码中的 以前写入流如下 os.write(getMsgHead(msgBytes.length)); 用了NIO之后写入流如下: ByteBuffer buffer = ByteBuffer.wrap(getMsgHead(msgBytes.length)); socketChannel.write(buffer); buffer.clear(); 改了以后没有出现异常了在linux下
  • 打赏
  • 举报
回复
饿 顶顶。请路人帮忙看看撒
dracularking 2013-01-30
  • 打赏
  • 举报
回复
如果仅从异常分析,broken pipe是由服务端与客户端之间数据的不同步引起的,具体原因可能会很多 看这里分析的一个例子: http://stackoverflow.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). 可能需要捕捉到该异常,并进行异常恢复处理。(因为导致不同步的原因可能是不可避免的)
brightyq 2013-01-30
  • 打赏
  • 举报
回复
用nio 。。

62,633

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧