java网络编程长连接的问题
Posted 征服
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java网络编程长连接的问题相关的知识,希望对你有一定的参考价值。
一. 网络程序运行过程中的常见异常及处理
第1个异常是 java.net.BindException:Address already in use: JVM_Bind。
该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监 听。此时用netstat –an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决这个问题。
第2个异常是java.net.ConnectException: Connection refused: connect。
该异常发生在客户端进行 new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端 口进行监听。出现该问题,首先检查客户端的ip和port是否写错了,如果正确则从客户端ping一下服务器看是否能ping通,如果能ping通(服务 服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动,这个肯定能解决这个问题。
第3个异常是java.net.SocketException: Socket is closed,
该异常在客户端和服务器均可能发生。异常的原因是 己方主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。
第4个异常是java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)。
该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭 (或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常 (Connection reset)。简单的说就是在连接断开后的读和写操作引起的。
第5个异常是java.net.SocketException: Broken pipe。
该异常在客户端和服务器均有可能发生。在第4个异常的第一种情况中(也就是抛出 SocketExcepton:Connect reset by peer:Socket write error后),如果再继续写数据则抛出该异常。前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接,其次是要检测对方的关闭连接操作,发现对 方关闭连接后自己也要关闭该连接。
二.编写网络程序时需 要注意的问题
第1个问题是要正确区分长、短连接。所谓的长连接是一经建立就永久保持。短连接就是在以下场景下,准备数据—>建立连接— >发送数据—>关闭连接。很多的程序员写了多年的网络程序,居然不知道什么是长连接,什么是短连接。
第2个问题是对长连接的维护。所谓的维护包括两个方面,首先是检测对方的主动断连(既调用 Socket的close方法),其次是检测对方的宕机、异常退出及网络不通。这是一个健壮的通信程序必须具备的。检测对方的主动断连很简单,主要一方主 动断连,另一方如果在进行读操作,则此时的返回值只-1,一旦检测到对方断连,则应该主动关闭己方的连接(调用Socket的close方法)。而检测对 方的宕机、异常退出及网络不通常用方法是用“心跳”,也就是双方周期性的发送数据给对方,同时也从对方接收“心跳”,如果连续几个周期都没有收到对方心 跳,则可以判断对方或者宕机或者异常推出或者网络不通,此时也需要主动关闭己方连接,如果是客户端可在延迟一定时间后重新发起连接。虽然Socket有一 个keep alive选项来维护连接,如果用该选项,一般需要两个小时才能发现对方的宕机、异常退出及网络不通。
第3个问题是处理效率问题。不管是客户端还是服务器,如果是长连接一个程序至少需要两个线程,一个用于接 收数据,一个用于发送心跳,写数据不需要专门的线程,当然另外还需要一类线程(俗称Worker线程)用于进行消息的处理,也就是说接收线程仅仅负责接收 数据,然后再分发给Worker进行数据的处理。如果是短连接,则不需要发送心跳的线程,如果是服务器还需要一个专门的线程负责进行连接请求的监听。这些 是一个通信程序的整体要求,具体怎么设计你的程序,就看你自己的设计水平了。
4 和zxccss的交互.因为开始短连接的话,不用考虑到线程的同步问题.现在做长连接,如果多个线程访问同一个 socket,这个全局的socket就需要进行资源保护,因为算法库是由zxccss的线程调用的,他的线程的运行机制我也不熟悉,发了邮件给 zxccss以前的作者李伟华,在深圳的李伟华虽然现在不做这个东西了,但是他很热情的帮我联系到了现在负责这个东西的同事,这里对他赞一个.后来问清了 zxccss的线程机制 ,用信号量的方法对全局长连接socket进行保护.修改代码.
5 和华为的交流问题,我不知道华为的态度是什么,反 正感觉是他们对这个项目不是很重视,投入的人力精力都不够,还好在各位同事的帮忙督促下,他们也在一点一点的做东西,其实中兴华为人家外面的人和称"中华 为兴",如果这个东西他们合作一些,至少可以在一半的时间内做好。我们做底层开发的还能做什么?不过是把手头的工作做好罢了.
6 这周和用服的 三个同事同吃同住同劳动,感觉到这这边的辛苦,没有一天是2点前岁的,早上9点过又去了.通过和他们交流,我越来越感觉到个东西.大家都觉得现在的版本管 理啊,项目升级啊有诸多的问题.我没有接触,感觉不深,但是这次这个zxcomsvr搞的我是很是郁闷的.从开发的角度来说,除了平时大家负责一点,多想 想自己的代码,少出点bug外,我们这边能不能建立一个bug数据库这样类似的东西,把开发,现场的bug想办法放到数据库中,以后遇到了,好去重现,或 去修改,或者大家把自己遇到的问题,解决方法都放到里面去,做个有效的搜索机制供别人使用,这自己虽然花的时间多了一点点,但是能为后来的人节省很多的时 间,这是我的一点不成熟的想法,只有个大概的概念。不过这种东西如果推广,应该可以受到大家,特别是前方用服的欢迎的。
以上是关于java网络编程长连接的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何高效维持网络长连接:手把手教你实现 自适应的心跳保活机制