java.net.SocketException: Broken pipe

转载来自:http://m635674608.iteye.com/blog/1491445 


Java代码  
1.java.net.SocketException: Broken pipe   
2.    at java.net.SocketOutputStream.socketWrite0(Native Method)   
3.    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)   
4.    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)   
5.    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)   
6.    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)   
7.    at java.io.DataOutputStream.flush(DataOutputStream.java:106)   
8.    at peer.UploadThread$SendToPeerThread.run(UploadThread.java:179)   
9.    at java.lang.Thread.run(Thread.java:680)  
java.net.SocketException: Broken pipe 
at java.net.SocketOutputStream.socketWrite0(Native Method) 
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) 
at java.net.SocketOutputStream.write(SocketOutputStream.java:136) 
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) 
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) 
at java.io.DataOutputStream.flush(DataOutputStream.java:106) 
at peer.UploadThread$SendToPeerThread.run(UploadThread.java:179) 
at java.lang.Thread.run(Thread.java:680) 网上查了很多资料,都说这个错误是由于Linux/Unix的连接数限制,或者多个线程对同一Socket进行读写。 
但是经过我反复调试的结果,这个异常顾名思义就是Socket通道坏掉了。可能是数据发送有延迟,对方没有检测到新数据,直接把通道关了,于是你再往里添加数据时就出现这个异常,通常往Socket里面写数据的Write函数只调用一遍时,是不会出现这个问题的,经常出现在循环中。解决方法是自己加入信息交换的协议,比如第一个数据报头标明数据长度;而接收端口在无法检测到新数据时不能立即退出,等接收的数据长度达到要求后,或者一定时间没有新数据再退出。 

在Unix/Linux下的网络结构和windows略有不同,至少在java的网络编程上有一些差异(没有考证,只是自己曾经遇到相同的问题!) 引起java.net.SocketException:Broken pipe这个异常的原因是你使用了多个线程同时对一个Socket通道进行读/写(windows环境没有这个问题),简单的说就是Unix/Linux下不能同时对一个Socket通道进行读和写。并且我也尝试过使用同步控制来防止对同一个Socket通道进行读和写,不过只是降低了该异常的发生概率(绝对不是同步控制有问题),发送和接收加入一段延迟后不会发生该问题,当然应用是不能容忍这样的处理效率和性能的。 最后我把整个网络通信改成用new io的非阻塞模式,在单线程中处理多路通道,没有这个问题,而且似乎系统吞吐量比先前更高了, 

3: 

java.net.SocketException: Broken pipe at java.net.SocketOutputStream.socketWrite0(Native Method) 一般出现在linux服务器上,常常由于网络不稳定或者服务器负荷过大,管道读端没有在读,而管道的写端继续有线程在写,就会造成管道中断。(由于管道是单向通信的) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。 以下是UNIX的信号解释: 11 / SIGSEGV: Unerlaubter Zugriff auf Hauptspeicher (Adressfehler). 12 / SIGUSER2: User-defined Signal 2 (POSIX). 把_JAVA_SR_SIGNUM改成12只是将信号至成user-defined,让它不报出来而已,不能解决问题。 建议采取的方式: 1. 资源没有完全释放,用完后要至NULL 值(JAVA的GC没那么完善) 2. 数据库连接顺序关闭!(RS,PS,CONN) 3. 优化JAVA虚拟机 加入相应的内存参数! 4. 不要在数据库中获取大段文本(即一个栏位的值不要太大) 5. JAVA 不推荐 用String 获取大量信息。(容易造成内存泄露,建议用StringBuffer) 6. 页面重复提交 7. 尽量将METHOD移到JAVA中,在JSP中所有的方法都看做全局变量,编译执行本身就有很多问题。 8. 如果是查询功能,尽可能的使用非XA(事务)。 9. 尽量用较新较稳定版本的JDK,低版本的JVM本身也有很多BUG,比如1。5的垃圾回收比起1。2,1。3一定是非常明显的进步。 10. LINUX系统本身没有这么稳定,有些问题无法避免的~~:) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值