`
seara
  • 浏览: 646453 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java网络编程从入门到精通(16):客户端套接字(Socket)的超时

阅读更多

本文为原创,如需转载,请注明作者和出处,谢谢!

上一篇:Java网络编程从入门到精通(15):为什么要使用SocketAddress来管理网络地址

客户端套接字的超时(timeout)就是指在客户端通过Socket和服务器进行通讯的过程中,由于网络延迟,网络阻塞等原因,造成服务器并未及时响应客户端的一种现象。在一段时间后,客户端由于未收到服务端的响应而抛出一个超时错误; 其中客户端所等待的时间就是超时时间。

由于生产超时错误的一端都是被动端;也就是说,这一端是在接收数据,而不是发送数据。对于客户端Socket来说,只有两个地方是在接收数据;一个是在连接服务器时;另一个是在连接服务器成功后,接收服务器发过来的数据时。因此,客户端超时也分为两种类型:连接超时和读取数据超时。

一、连接超时

这种超时在前面的例子中已经使用过。在Socket类中只有通过connect方法的第二个参数才能指定连接超时的时间。由于使用connect方法连接服务器必须要指定IP和端口;因此,无效的IP或端口将会引发连接超时错误。

二、读取数据超时

在连接服务器成功后,Socket所做的最重要的两件事就是接收数据发送数据;而在接收数据时可能因为网络延迟、网络阻塞等原因,客户端一直处于等待状态;而客户端在等待一段时间后,如果服务器还没有发送数据到客户端,那么客户端Socket将会抛出一个超时错误。

我们可以通过Socket类的setSoTimeout方法来设置读取数据超时的时间;时间的单位是毫秒。这个方法必须在读取数据之前调用才会生效。如果将超时时间设为0,则不使用超时时间;也就是说,客户端什么时候和服务器断开,将完全取决于服务端程序的超时设置。如下面的语句将读取数据超时时间设为5秒。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->Socketsocket=newSocket();
socket.setSoTimeout(
5000);
socket.connect(……);
socket.getInputStream().read();

要注意的是不要将设置连接超时和读取数据超时设置得太小,如果值太小,如100,可能会造成服务器的数据还没来得及发过来,客户端就抛出超时错误的现象。下面的代码给出了一个用于测试连接超时和读取数据超时的例子。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->package mynet;

importjava.net.*;

publicclass SocketTimeout
{
publicstaticvoidmain(String[]args)
{
longtime1=0,time2=0;
Socketsocket
=newSocket();
try
{
if(args.length<4)
{
System.out.println(
"参数错误!");
return;
}

time1
=System.currentTimeMillis();
socket.connect(
newInetSocketAddress(args[0],Integer
.parseInt(args[
1])),Integer.parseInt(args[2]));
socket.setSoTimeout(Integer.parseInt(args[
3]));
time1
=System.currentTimeMillis();
socket.getInputStream().read();
}
catch(SocketTimeoutExceptione)
{
if(!socket.isClosed()&&socket.isConnected())
System.out.println(
"读取数据超时!");
else
System.out.println(
"连接超时");
}
catch(Exceptione)
{
System.out.println(e.getMessage());
}
finally
{
time2
=System.currentTimeMillis();
System.out.println(time2
-time1);
}
}
}

SocketTimeout类的main方法需要4个参数:IP(域名)、端口、连接超时、读取数据超时。下面让我们来用一组数据来测试这个例子。

测试1 :无效IP引发的超时错误

执行如下命令:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->javamynet.SocketTimeout192.168.18.248030005000

运行结果:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->连接超时
3045

注意:192.168.18.24是一个无效的IP;如果这个IP在网络环境中存在,请换其它的无效的IP。在这个测试用例中不能将无效的IP换成无效的域名;这是因为如果使用了域名来连接服务器,Java会先通过DNS将域名映射成相应的IP;如果这个域名是无效的,在映射的过程中就会出错;因此,程序也就不会执行连接服务器操作,自然也就不会抛出“连接超时”错误了。

测试2 :无效端口引发的超时错误

执行如下命令:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->javamynet.SocketTimeoutwww.ptpress.com.cn888830005000

运行结果:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->连接超时
3075

测试3 :读取数据超时错误

执行如下命令:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->javamynet.SocketTimeoutwww.ptpress.com.cn8030005000

运行结果:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->读取数据超时!
5008

测试4 :将读取数据超时设为0的效果

执行如下命令:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->javamynet.SocketTimeoutwww.ptpress.com.cn8030000

运行结果:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->Connectionreset
131519

从前3个测试的输出结果不难看出,每个测试用例都将连接超时和读取数据超时分别设为30005000毫秒;而它们的运行结果并不是30005000毫秒,而是在所设定的超时时间的左右摇摆;这主要是因为系统所输出的时间并不都是超时时间;如有一些时间是Java处理错误、向控制台输出信息的时间。另外,由于系统计时的误差,也会影响到超时时间的准确性。但不管怎样,超时时间总会在所设定的时间周围摇摆。

对于测试4,将读取数据超时设为0后,SocketTimeout类经过了2分多钟(131519毫秒)才抛出Connection reset错误。这个抛出错误的时间和服务端程序的超时设置有关;也就是这个错误是由于服务端程序主动将客户端网络连接断开而产生的。

下一篇:
Java网络编程从入门到精通(17):Socket类的getter和setter方法(1)



国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

分享到:
评论

相关推荐

    java网络编程从入门到精通

    Java网络编程是开发分布式应用...通过阅读"Java网络编程从入门到精通"这本书,你将系统地学习到以上所有内容,并通过实例和练习加深理解,从而在实际项目中灵活运用这些知识,成为一名精通Java网络编程的专业开发者。

    Java网络编程从入门到精通

    本教程"Java网络编程从入门到精通"旨在帮助初学者和有经验的开发者深入理解这一领域,从基础知识到高级主题,提供了一套全面的学习资源。 在Java中,网络编程主要涉及以下核心知识点: 1. **Socket编程**:Java的...

    socket 套接字 Java 套接字 编程

    Java套接字编程是网络通信的核心技术之一,主要用于实现客户端与服务器之间的数据交换。本文将深入探讨Java中的Socket编程,包括基本概念、工作原理、创建和使用Socket的过程,以及常见问题和解决策略。 1. 基本...

    C_socket编程从入门到精通

    C_socket编程是网络编程的基础,它...从创建套接字到建立连接,再到数据传输和连接管理,每一个环节都需要深入理解和实践。通过本教程,你将逐步成长为一名熟练的C_socket程序员,能够独立完成各种复杂的网络编程任务。

    JAVA网络编程资料(1)-Socket套接字—Java套接字编程.chm

    JAVA网络编程资料(1)-Socket套接字—Java套接字编程.chm

    Socket套接字—Java套接字编程

    Socket套接字是Java编程语言中用于网络通信的核心组件,它是实现客户端-服务器模型的基础。在Java中,Socket和ServerSocket类提供了套接字编程的基本功能。本文将深入探讨Java套接字编程的相关知识点,包括Socket和...

    套接字socket编程文档

    在IT领域,套接字(Socket)编程是网络通信的核心技术之一,它为应用程序提供了低级别的、进程间的通信机制。套接字允许不同计算机上的进程相互通信,无论是同在一个局域网还是跨越互联网。本篇文章将深入探讨套接字...

    基于Java的Socket套接字编程 源代码

    Java的Socket套接字编程是网络通信中的基础技术,它提供了两台计算机间低级别的连接。在Java中,Socket类和ServerSocket类是实现客户端-服务器通信的核心组件。本资源包含的是基于Java的Socket套接字编程的源代码...

    java中socket套接字定义与使用

    总的来说,Java中的Socket套接字是实现网络通信的核心工具,无论是基于TCP的稳定传输还是UDP的高效传输,都能通过Socket灵活地构建网络应用。在实际开发中,开发者应根据应用的需求和场景选择合适的通信协议,以实现...

    JAVA网络编程从入门到精通

    ### JAVA网络编程从入门到精通知识点详解 #### 一、Internet地址概述 互联网中的每一台设备都需要有一个唯一的标识符——IP地址。当前广泛使用的IPv4地址由四个字节组成,而未来的趋势是采用16个字节的IPv6地址。 ...

    JAVA网络编程学习资料以及源代码Socket套接字网络协议

    Java网络编程是开发分布式应用程序的关键技术,而Socket套接字是实现网络通信的基础。本学习资料包涵盖了关于Java网络编程的全面知识,包括Socket套接字的使用和网络协议的理解。 首先,我们要理解Java中的Socket。...

    Java 套接字编程Java 套接字编程

    Java作为一种广泛应用的编程语言,提供了丰富的API支持网络编程,尤其是对于套接字(Socket)编程的支持。本文将详细介绍Java套接字编程的基本概念、原理以及实际操作方法。 #### 二、Java网络编程概述 Java网络编程...

    Java Socket 套接字编程经典入门

    Java Socket编程经典的入门教程(包含源代码) Socket即套接字 java.net包的客户端Socket,服务端ServerSocket; 单线程套接字客户端和服务端的处理; 服务端多线程处理客户端套接字; 带有线程池处理客户端套接字;...

    C#socket编程从入门到精通

    在探讨C# socket编程的过程中,我们首先需要了解的是如何操作IP地址,这是进行网络通信的基础。C#中的IPAddress类提供了方便的方法...对于希望从入门到精通C# socket编程的读者而言,这些内容是必须掌握的核心知识点。

    Java网络编程案例教程习题参考答案 .pdf

    包括Socket编程、TCP/IP协议、Java Socket类、ServerSocket类、Java网络编程模型、网络编程常见问题、多线程编程、并发编程、Socket选项、网络安全、数据传输、网络协议、Socket超时、网络异常处理等。

    java学习从入门到精通教程(pdf)

    这个“Java学习从入门到精通”教程覆盖了Java编程的各个方面,无论是初学者还是有一定经验的开发者,都能从中受益。通过深入学习和实践,你将能够熟练掌握Java编程,为未来的开发工作打下坚实的基础。

    网络套接字实现服务器返回客户机发送数据

    "网络套接字实现服务器返回客户机发送数据"这个标题涉及到的是客户端-服务器(Client-Server)架构中的数据交互过程。下面将详细阐述网络套接字的工作原理、如何实现服务器响应客户端发送的数据,以及相关的编程知识...

    Java Socket网络编程.pdf

    Java的Socket编程接口提供了丰富的功能,包括错误处理、套接字选项设置等,使得开发者能够构建复杂、可靠的网络应用。同时,Java的异常处理机制也为网络编程提供了良好的健壮性。在实际开发中,还需要考虑线程管理、...

    基于UDP和TCP协议的Socket(网络编程/套接字)案例

    Socket,也被称为套接字,是网络编程中的一个重要概念,它是不同计算机进程间通信的一种机制。在Java中,Socket提供了一种标准的方式来实现基于TCP(传输控制协议)和UDP(用户数据报协议)的网络通信。这两种协议在...

Global site tag (gtag.js) - Google Analytics