




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JAVA Socket超时浅析 套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的“终端”。针对一个特定的连接,每台机器上都有一个“套接字”,可以想象它们之间有一条虚拟的“线缆”。JAVA有两个基于数据流的套接字类:ServerSocket,服务器用它“侦听”进入的连接;Socket,客户端用它初始一次连接。侦听套接字只能接收新的连接请求,不能接收实际的数据包。 套接字是基于TCP/IP实现的,它是用来提供一个访问TCP的服务接口,或者说套接字socket是TCP的应用编程接口API,通过它应用层就可以访问TCP提供的服务。在JAVA中,我们用ServerSocket、Socket类创建一个套接字连接,从套接字得到的结果是一个InputStream以及OutputStream对象,以便将连接作为一个IO流对象对待。通过IO流可以从流中读取数据或者写数据到流中,读写IO流会有异常IOException产生。 套接字底层是基于TCP的,所以socket的超时和TCP超时是相同的。下面先讨论套接字读写缓冲区,接着讨论连接建立超时、读写超时以及JAVA套接字编程的嵌套异常捕获和一个超时例子程序的抓包示例。1 socket读写缓冲区 一旦创建了一个套接字实例,操作系统就会为其分配缓冲区以存放接收和要发送的数据。 JAVA可以设置读写缓冲区的大小-setReceiveBufferSize(int size), setSendBufferSize(int size)。 向输出流写数据并不意味着数据实际上已经被发送,它们只是被复制到了发送缓冲区队列SendQ,就是在Socket的OutputStream上调用flush()方法,也不能保证数据能够立即发送到网络。真正的数据发送是由操作系统的TCP协议栈模块从缓冲区中取数据发送到网络来完成的。 当有数据从网络来到时,TCP协议栈模块接收数据并放入接收缓冲区队列RecvQ,输入流InputStream通过read方法从RecvQ中取出数据。2 socket连接建立超时 socket连接建立是基于TCP的连接建立过程。TCP的连接需要通过3次握手报文来完成,开始建立TCP连接时需要发送同步SYN报文,然后等待确认报文SYN+ACK,最后再发送确认报文ACK。TCP连接的关闭通过4次挥手来完成,主动关闭TCP连接的一方发送FIN报文,等待对方的确认报文;被动关闭的一方也发送FIN报文,然等待确认报文。 正在等待TCP连接请求的一端有一个固定长度的连接队列,该队列中的连接已经被TCP接受(即三次握手已经完成),但还没有被应用层所接受。TCP接受一个连接是将其放入这个连接队列,而应用层接受连接是将其从该队列中移出。应用层可以通过设置backlog变量来指明该连接队列的最大长度,即已被TCP接受而等待应用层接受的最大连接数。 当一个连接请求SYN到达时,TCP确定是否接受这个连接。如果队列中还有空间,TCP模块将对SYN进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文收到后才会知道这个新连接。如果队列没有空间,TCP将不理会收到的SYN。 如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,新的连接请求可能不被响应而会超时。如果一个连接请求SYN发送后,一段时间后没有收到确认SYN+ACK,TCP会重传这个连接请求SYN两次,每次重传的时间间隔加倍,在规定的时间内仍没有收到SYN+ACK,TCP将放弃这个连接请求,连接建立就超时了。 JAVA Socket连接建立超时和TCP是相同的,如果TCP建立连接时三次握手超时,那么导致Socket连接建立也就超时了。可以设置Socket连接建立的超时时间-connect(SocketAddress endpoint, int timeout)如果在timeout内,连接没有建立成功,在TimeoutException异常被抛出。如果timeout的值小于三次握手的时间,那么Socket连接永远也不会建立。 不同的应用层有不同的连接建立过程,Socket的连接建立和TCP一样-仅仅需要三次握手就完成连接,但有些应用程序需要交互很多信息后才能成功建立连接,比如Telnet协议,在TCP三次握手完成后,需要进行选项协商之后,Telnet连接才建立完成。3 socket读超时 如果输入缓冲队列RecvQ中没有数据,read操作会一直阻塞而挂起线程,直到有新的数据到来或者有异常产生。调用setSoTimeout(int timeout)可以设置超时时间,如果到了超时时间仍没有数据,read会抛出一个SocketTimeoutException,程序需要捕获这个异常,但是当前的socket连接仍然是有效的。 如果对方进程崩溃、对方机器突然重启、网络断开,本端的read会一直阻塞下去,这时设置超时时间是非常重要的,否则调用read的线程会一直挂起。 TCP模块把接收到的数据放入RecvQ中,直到应用层调用输入流的read方法来读取。如果RecvQ队列被填满了,这时TCP会根据滑动窗口机制通知对方不要继续发送数据,本端停止接收从对端发送来的数据,直到接收者应用程序调用输入流的read方法后腾出了空间。4 socket写超时 socket的写超时是基于TCP的超时重传。超时重传是TCP保证数据可靠性传输的一个重要机制,其原理是在发送一个数据报文后就开启一个计时器,在一定时间内如果没有得到发送报文的确认ACK,那么就重新发送报文。如果重新发送多次之后,仍没有确认报文,就发送一个复位报文RST,然后关闭TCP连接。首次数据报文发送与复位报文传输之间的时间差大约为9分钟,也就是说如果9分钟内没有得到确认报文,就关闭连接。但是这个值是根据不同的TCP协议栈实现而不同。 如果发送端调用write持续地写出数据,直到SendQ队列被填满。如果在SendQ队列已满时调用write方法,则write将被阻塞,直到SendQ有新的空闲空间为止,也就是说直到一些字节传输到了接收者套接字的RecvQ中。如果此时RecvQ队列也已经被填满,所有操作都将停止,直到接收端调用read方法将一些字节传输到应用程序。 当Socket的write发送数据时,如果网线断开、对端进程崩溃或者对端机器重启动,TCP模块会重传数据,最后超时而关闭连接。下次如再调用write会导致一个异常而退出。 Socket写超时是基于TCP协议栈的超时重传机制,一般不需要设置write的超时时间,也没有提供这种方法。5 双重嵌套异常捕获 如果ServerSocket、Socket构造失败,只需要仅仅捕获这个构造失败异常而不需要调用套接字的close方法来释放资源(必须保证构造失败后不会留下任何需要清除的资源),因为这时套接字内部资源没有被成功分配。如果构造成功,必须进入一个try finally语句块里调用close释放套接字。请参照下面例子程序。 java view plaincopy 1 import .*; 2 import java.io.*; 3 public class SocketClientTest 4 5 public static final int PORT = 8088; 6 public static void main( String args ) throws Exception 7 8 InetAddress addr = InetAddress.getByName( ); 9 Socket socket = new Socket(); 10 try 11 12 socket.connect( new InetSocketAddress( addr, PORT ), 30000 ); 13 socket.setSendBufferSize(100); 14 15 BufferedWriter out = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); 16 int i = 0; 17 18 while( true ) 19 20 System.out.println( client sent - hello * + i+ ); 21 out.write( client sent - hello * + i ); 22 out.flush(); 23 24 Thread.sleep( 1000 ); 25 26 27 finally 28 29 socket.close(); 30 31 32 java view plaincopy 33 import java.io.*; 34 import .ServerSocket; 35 import .Socket; 36 public class SocketServerTest 37 38 public static final int PORT = 8088; 39 public static final int BACKLOG = 2; 40 public static void main( String args ) throws IOException 41 42 ServerSocket server = new ServerSocket( PORT, BACKLOG ); 43 System.out.println(started: + server); 44 try 45 46 Socket socket = server.accept(); 47 try 48 49 BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); 50 String info = null; 51 52 while( ( info = in.readLine() ) != null ) 53 54 System.out.println( info ); 55 56 57 finally 58 59 socket.close(); 60 61 62 finally 63 64 server.close(); 65 66 67 执行上面的程序,在程序运行一会儿之后,断开client和server之间的网络连接,在机器上输出如下: Server上的输出: Echoing:client sent -hello0 Echoing:client sent -hello1Echoing:client sent -hello2Echoing:client sent -hello3Echoing:client sent -hello4Echoing:client sent -hello5Echoing:client sent -hello6 - 断开了网络连接之后没有数据输出 Client上的输出:socket default timeout = 0socket = Socketaddr=/9,port=8088,localport=4691begin to readclient sent - hello * 0client sent - hello * 1client sent - hello * 2client sent - hello * 3client sent - hello * 4client sent - hello * 5client sent - hello * 6client sent - hello * 7client sent - hello * 8 client sent - hello * 9client sent - hello * 10 - 断开网络连接后客户端进程挂起 .SocketException : Connection reset by peer: socket write error at .SocketOutputStream.socketWrite0( Native Method ) at .SocketOutputStream.socketWrite( SocketOutputStream.java:92 ) at .SocketOutputStream.write( SocketOutputStream.java:136 ) at sun.nio.cs.StreamEncoder.writeBytes( StreamEncoder.java:202 ) at sun.nio.cs.StreamEncoder.implFlushBuffer( StreamEncoder.java:272 ) at sun.nio.cs.StreamEncoder.implFlush( StreamEncoder.java:276 ) at sun.nio.cs.StreamEncoder.flush( StreamEncoder.java:122 ) at java.io.OutputStreamWriter.flush( OutputStreamWriter.java:212 ) at java.io.BufferedWriter.flush( BufferedWriter.java:236 ) at com.xtera.v
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030中国城镇燃气管道建设现状评估与发展规划研究报告
- 2025-2030中国城市轨道交通设备市场需求与供给预测报告
- 2025-2030中国啤酒风味稳定性技术突破与保质期延长方案报告
- 安全员c3上海证练习题库及答案解析
- 2025-2030中国啤酒行业线上线下融合营销模式创新与实践报告
- 电动车安全驾驶常识题库及答案解析
- 2025-2030中国啤酒行业客户投诉大数据分析与服务改进报告
- 2025-2030中国啤酒行业包装材料环保化转型可行性研究报告
- 2025-2030中国啤酒行业会展经济效应分析与营销活动ROI评估研究报告
- 2025-2030中国啤酒经销商体系优化与渠道动力激活策略报告
- 高血压糖尿病健康管理督导记录表
- 《医疗机构基本标准(试行)》2018年版
- 医院检验标本采集与运送
- 秋冬季猪的饲养管理课件(模板)
- 新能源汽车技术全套ppt
- 2022年8月20日云南省省直机关遴选笔试真题及答案解析
- 现代医学实验动物科学和比较医学研究
- SOP标准作业指导书样板
- 云南省地图含市县地图矢量分层地图行政区划市县概况ppt模板
- GB/T 41843-2022功能、残疾、健康分类的康复组合评定
- 压花艺术课件
评论
0/150
提交评论