在java网络编程Socket通信中通常会遇到以下异常情况
第个异常是 BindException:Address already in use: JVM_Bind
该异常发生在服务器端进行new ServerSocket(port)(port是一个的整型值)操作时异常的原因是以为与port一样的一个端口已经被启动并进行监听此时用netstat an命令可以看到一个Listending状态的端口只需要找一个没有被占用的端口就能解决该问题了
第个异常是ConnectException: Connection refused: connect
该异常发生在客户端进行 new Socket(ip port)操作时该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由)或者是该ip存在但找不到指定的端口进行监听出现该问题首先检查客户端的ip和port是否写错如果正确则从客户端ping一下服务器看是否能ping通如果能ping通(服务器端把ping禁掉则需要另外的办法)则看在服务器端的监听指定端口的程序是否启动这个肯定能解决这个问题
第个异常是SocketException: Socket is closed
该异常在客户端和服务器均可能发生异常的原因是本端主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作
第个异常是SocketException: (Connection reset或者Connect reset by peer:Socket write error)
该异常在客户端和服务器端均有可能发生引起该异常的原因有两个第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭)另一端仍发送数据发送的第一个数据包引发该异常(Connect reset by peer)另一个是一端退出但退出时并未关闭该连接另一端如果在从连接中读数据则抛出该异常(Connection reset)简单的说就是由连接断开后的读和写操作引起的
第个异常是SocketException: Broken pipe
该异常在客户端和服务器均有可能发生在第个异常的第一种情况中(也就是抛出 SocketExcepton:Connect reset by peer:Socket write error后)如果再继续写数据则抛出该异常前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接其次是要检测对方的关闭连接操作发现对方关闭连接后自己也要关闭该连接
二.编写网络程序时需要注意的问题:
是要正确区分长短连接所谓的长连接是指一经建立就永久保持短连接的情况是准备数据—>建立连接—>发送数据—>关闭连接很多的程序员写了多年的网络程序居然不知道什么是长连接什么是短连接
是对长连接的维护所谓维护包括两个方面首先是检测对方的主动断连(即调用 Socket的close方法)其次是检测对方的宕机异常退出及网络不通这是一个健壮的通信程序必须具备的检测对方的主动断连很简单主要一方主动断连另一方如果在进行读操作则此时的返回值只一旦检测到对方断连则应该主动关闭本端的连接(调用Socket的close方法)而检测对方的宕机异常退出及网络不通常用方法是用心跳也就是双方周期性的发送数据给对方同时也从对方接收心跳如果连续几个周期都没有收到对方心跳则可以判断对方宕机异常退出或者网络不通此时也需要主动关闭本端连接如果是客户端可在延迟一定时间后重新发起连接虽然Socket有一个keep alive选项来维护连接如果用该选项一般需要两个小时才能发现对方的宕机异常退出及网络不通
是处理效率问题不管是客户端还是服务器如果是长连接一个程序至少需要两个线程一个用于接收数据一个用于发送心跳写数据不需要专门的线程当然另外还需要一类线程(俗称Worker线程)用于进行消息的处理也就是说接收线程仅仅负责接收数据然后再分发给Worker进行数据的处理如果是短连接则不需要发送心跳的线程如果是服务器还需要一个专门的线程负责进行连接请求的监听这些是一个通信程序的整体要求具体到你的程序中就看你如何对程序进行优化了