做网络编程的人对setSoTimeout方法一定很熟悉,都知道是设置连接的超时时间!
但是我在网上找资料时发现很多人把这个超时时间理解成了链路的超时时间!我看了一下JDK 关于这个方法的说明,其实根本不是链路的超时时间!
setSoTimeout public void setSoTimeout(int timeout) throws SocketException启用/禁用带有指定超时值的 SO_TIMEOUT,以毫秒为单位。将此选项设为非零的超时值时,在与此 Socket 关联的 InputStream 上调用 read() 将只阻塞此时间长度。 如果超过超时值,将引发 java.net.SocketTimeoutException,虽然 Socket 仍旧有效。选项必须在进入阻塞操作前被启用才能生效。 超时值必须是 > 0 的数。超时值为 0 被解释为无穷大超时值。 参数: timeout - 指定的以毫秒为单位的超时值。 抛出: SocketException - 如果底层协议出现错误,例如 TCP 错误。 从以下版本开始: JDK 1.1 另请参见: getSoTimeout()
其实说白了他只是read方法的超时时间,这个方法是堵塞的!
写个小例子验证一下:
服务端,收到一个请求后处理,但是只处理一个请求,处理完毕后结束:
package socket; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class SocketService { public static void main(String[] args) { try { SocketAddress address = new InetSocketAddress("192.168.9.155", 30001); // 启动监听端口 8001 ServerSocket ss = new ServerSocket(); ss.bind(address); // 接收请求 Socket s = ss.accept(); new Thread(new T(s)).start(); } catch (Exception e) { e.printStackTrace(); } } } class T implements Runnable { public void run() { try { System.out.println(socket.toString()); socket.setKeepAlive(true); socket.setSoTimeout(5 * 1000); String _pattern = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat format = new SimpleDateFormat(_pattern); while (true) { System.out.println("开始:" + format.format(new Date())); try { InputStream ips = socket.getInputStream(); ByteArrayOutputStream bops = new ByteArrayOutputStream(); int data = -1; while((data = ips.read()) != -1){ System.out.println(data); bops.write(data); } System.out.println(Arrays.toString(bops.toByteArray())); }catch(SocketTimeoutException e){ e.printStackTrace(); }catch(SocketException e){ e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } Thread.sleep(1000); System.out.println(socket.isBound()); // 是否邦定 System.out.println(socket.isClosed()); // 是否关闭 System.out.println(socket.isConnected()); // 是否连接 System.out.println(socket.isInputShutdown()); // 是否关闭输入流 System.out.println(socket.isOutputShutdown()); // 是否关闭输出流 System.out.println("结束:" + format.format(new Date())); } } catch (Exception e) { e.printStackTrace(); } } private Socket socket = null; public T(Socket socket) { this.socket = socket; } public Socket getSocket() { return socket; } public void setSocket(Socket socket) { this.socket = socket; } }
第一个客户端,连接后一直保持连接对象的存活,但是不发送数据,服务端打印:
package socket; import java.net.Socket; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("192.168.9.155", 30001); socket.setKeepAlive(true); while(true && null != socket){ Thread.sleep(10 * 1000); } } catch (Exception e) { e.printStackTrace(); } } }
打印如下,可以看到链路一直是活的,间隔超时时间的间隔就打印一组异常信息:
Socket[addr=/192.168.9.155,port=3017,localport=30001] 开始:2012-11-14 11:15:30 java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at socket.T.run(SocketService.java:42) at java.lang.Thread.run(Unknown Source) true false true false false 结束:2012-11-14 11:15:36 开始:2012-11-14 11:15:36 java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at socket.T.run(SocketService.java:42) at java.lang.Thread.run(Unknown Source) true false true false false 结束:2012-11-14 11:15:42 开始:2012-11-14 11:15:42
然后我们编写一个客户端,连接后马上关闭连接,也不发送任何数据:
package socket; import java.net.Socket; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("192.168.9.155", 30001); socket.setKeepAlive(true); } catch (Exception e) { e.printStackTrace(); } } }
打印如下:
开始:2012-11-14 11:17:42 java.net.SocketException: Connection reset at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at socket.T.run(SocketService.java:42) at java.lang.Thread.run(Unknown Source) true false true false false java.net.SocketException: Connection reset at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at socket.T.run(SocketService.java:42) at java.lang.Thread.run(Unknown Source) 结束:2012-11-14 11:17:43 开始:2012-11-14 11:17:43 true false true false false 结束:2012-11-14 11:17:44
异常是不一样的,不一样的还有,如果是超时,则五秒钟循环一次,然后是连接中断,则不在循环马上再报错,因为连接已经挂了!但是打印这个连接还是有效的,这个我也不知道怎么回事!
所以,如果大家理解为超时时间内没有数据连接就自动关闭或失效,那么这个理解就非常有问题了!
请您到ITEYE看我的原创:http://cuisuqiang.iteye.com
或支持我的个人博客,地址:http://www.javacui.com
相关推荐
提供一个c# socket连接池设计的例子,解决socket并发连接限制的问题,并且提供一种设置连接超时时间的方法,默认连接超时时间是不能设置的,提供了socket网络发送数据的接口.可用于pos小票打印机通讯。
1. **设置连接超时**: 易语言提供了设置Socket连接超时的API,比如`设置网络连接超时`命令,可以指定一个时间值(单位通常为毫秒),如果在这个时间内未完成连接,将会返回错误。 2. **异常处理**: 在进行...
在 Linux 环境下,设置套接字(Socket)连接超时是一件非常重要的事情。下面我们将详细介绍 Linux 下 Socket 连接超时的一种实现方法。 首先,需要创建套接字,并将其设置成非阻塞状态。这是因为在连接时,我们不...
在Windows环境下进行网络编程时,有时需要对socket连接进行超时控制,特别是在客户端与服务器通信的过程中,如果连接请求长时间没有响应,程序可能会陷入无休止的等待状态,从而导致资源浪费甚至程序卡死。...
易语言socket连接超时例程源码,socket连接超时例程,子程序1,socket,htons,inet_addr,Connect,closesocket,WSAStartup,setsockopt,ioctlsocket,select
同时,对于服务器性能或网络状况不佳的情况,适当的超时时间设置也至关重要。如果超时时间设置得过短,可能会频繁触发异常;如果设置得过长,可能会延迟程序的响应。因此,根据具体应用场景调整超时时间是非常必要的...
Java中Socket设置连接超时的代码分享 Java 中 Socket 设置连接超时是非常重要的,因为如果超时时长过长的...Java 中 Socket 设置连接超时是非常重要的,它可以帮助我们避免由于长时间等待连接而影响测试和用户体验。
2. 使用`setsockopt()`函数设置连接超时和读/写超时。 3. 处理非阻塞模式下的`WSAEWOULDBLOCK`错误码。 4. 在非阻塞模式下,可能需要多次尝试读取或写入以确保所有数据都被正确处理。 在实际开发中,理解并正确运用...
- **关闭策略**:合理设置超时时间,当连接长时间无数据传输时,可以考虑关闭连接以释放资源。 **4. 应用场景** 短连接适合一次性、低延迟、资源有限的场景,如网页浏览。而长连接适合实时性强、需要持续交互的...
在网络通信中,由于各种原因(如网络延迟、服务器繁忙等),socket连接可能会出现长时间无法完成的情况,这时就需要设置连接超时机制。超时机制可以避免程序因为等待连接响应而无限期阻塞,提高程序的健壮性和用户...
源代码通常包括了创建Socket对象、设置连接超时参数、发起连接尝试以及处理超时异常等关键步骤。开发者可以通过阅读和分析这段代码,学习如何在易语言中处理网络连接的超时问题。 "源码使用说明.txt"文件则为用户...
1. 初始化连接池:设置最大连接数、最小连接数、超时时间等参数,并预创建一部分Socket连接。 2. 获取连接:当应用程序需要建立Socket连接时,从连接池中获取一个闲置的Socket,如果没有,则等待直到有连接被归还或...
利用新建类,异步传送参数,解决断连接向多个ip发送socket包产生socket.connect超时的问题。实现向每一个ip发送包新建立一个线程,由于是新建立的线程,全部异步,所以没法记录文本文件(同一个文件同时被记录),...
对于HTTP代理,可能需要在连接前构造一个`HttpWebRequest`对象,设置其代理属性,然后通过`HttpWebRequest.GetResponse()`获取到连接,再从连接中获取Socket。 5. **建立连接**:使用`Socket.Connect()`方法连接到...
接着,通过调用`settimeout(100)`方法将其超时时间设置为100秒,并再次打印确认。 #### 三、Socket超时的获取方法 可以通过`gettimeout()`方法来获取当前Socket对象的超时时间。如果之前未设置超时时间,则返回...
在Java中,我们可以使用Socket对象的setSoTimeout()方法来设置一个特定的等待时间。如果在这个时间内没有接收到数据,将会抛出SocketTimeoutException异常,从而中断阻塞状态。 然而,传统的Socket编程模型通常使用...
在实际应用中,可能还需要处理异常、超时、重试等问题,确保连接的稳定性和打印的可靠性。同时,为了提高安全性,可能需要对数据进行加密传输,或者使用认证机制来防止未经授权的访问。 在压缩包“Send”中,可能...
socket 接收多个终端上传的数据 ,每个终端新建一个socket,超时的socket定时清理,防止连接过多影响服务器性能
3. 重试策略:设置合理的重试次数和间隔时间,防止频繁重连对服务器造成压力。 4. 断线通知:在重连过程中,客户端可能需要通知用户当前的连接状态,以便用户了解情况。 在压缩包中的`iSocket`文件可能是实现这个...
在实际应用中,合理设置连接池的参数至关重要,包括最小连接数、最大连接数、超时时间等。这些参数需要根据系统的并发量、网络环境以及服务器处理能力进行调整,以达到最佳性能。 总结来说,Socket客户端连接池是...