当前位置:   article > 正文

FTPClient 超时处理_ftpreply.ispositivecompletion

ftpreply.ispositivecompletion

apache 开源库:commons-net 超时处理。

Socket有2个阻塞

第1个阻塞:TCP的三次握手 connectTimeout

TCP通过三次握手,建立连接,这个过程,类似我们在信号不好的时候打电话的过程:
客户端:喂,能听到我说话吗
服务端:我能听到,你能听到我吗
客户端:能听到

  1. Socket socket = new Socket();
  2. socket.connect(new InetSocketAddress("localhost", 8080));

当 socket 客户端执行 socket.connect() 方法时,客户端请求和服务端建立tcp连接时,会一直阻塞直到连接建立成功,或抛异常。当设置了connectTimeout, 客户端请求和服务端建立连接时,阻塞时间超过connectTimeout时,就会抛出异常java.net.ConnectException: Connection timed out: connect。

第2个阻塞:读取输入流 soTimeout

  1. Socket socket = new Socket();
  2. socket.connect(new InetSocketAddress("localhost", 8080));
  3. socket.getInputStream().read();

当调用socket.getInputStream().read()方法时,由于这个read()方法是阻塞的,read()方法会一直处于阻塞状态等待接受数据,直到服务端往输出流中响应数据 而导致不能往下执行代码;而setSoTimeout()方法就是设置阻塞的超时时间.当设置了超时时间后,如果read()方法读不到数据,处于等待读取数据的状态时,就会开始计算超时时间;当到达超时时间还没有新的数据可以读取的时候,read()方法就会抛出io异常,结束read()方法的阻塞状态;如果到达超时时间前,从缓冲区读取到了数据,那么就重新计算超时时间.当不设置这个参数时,默认值为无穷大,即InputStream的read方法会一直阻塞下去,除非连接断开。

FTPClient 一共有 6 个设置超时的接口,而不管是文件上传或下载,这过程,FTP 都会创建两个 Socket,一个用于传输控制命令,一个用于传输文件数据,超时接口和这两个 Socket 之间的关系如下:

setConnectTimeout() 用于设置终端 Socket 与 FTP 服务器建立连接这个过程的超时时间。

setDefaultTimeout() 用于设置终端的传输控制命令的 Socket 的 SoTimeout,即针对传输控制命令的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。

setSoTimeout() 作用跟上个方法一样,区别仅在于该方法设置的超时会覆盖掉上个方法设置的值。

setDataTimeout() 用于设置终端的传输数据的 Socket 的 Sotimeout,即针对传输文件数据的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。

setControlKeepAliveTimeout() 用于设置当处于传输数据过程中,按指定的时间阈值定期让传输控制命令的 Socket 发送一个无操作命令 NOOP 给服务器,让它 keep alive。

setControlKeepAliveReplyTimeout():只有调用上个方法后,该方法才能生效,用于设置在传输数据这个过程中,暂时替换掉传输控制命令的 Socket 的 SoTimeout,传输过程结束恢复这个 Socket 原本的 SoTimeout。

超时接口大概的用途明确了,那么再稍微来讲讲该怎么用:

针对使用 FTPClient 下载 FTP 文件,一般只需使用三个超时接口,

setDefaultTimeout(毫秒)用于设置传输控制命令的 Socket 的 SoTimeout 的超时处理,

一个是 setConnectTimeout(毫秒),用于设置建立连接过程中的超时处理,

而另一个则是 setDataTimeout(毫秒),用于设置传输数据的 Socket 的 SoTimeout 的超时处理,

  1. public boolean login(String ip, int port, String username, String password) {
  2. ftpClient = new FTPClient();
  3. try {
  4. logger.info("connecting...ftp服务器:" + ip + ":" + port);
  5. ftpClient.setControlEncoding("UTF-8");// 编码设置必须放在connect前不然不起作用
  6. ftpClient.setConnectTimeout(5000);//tcp握手连接超时,单位毫秒
  7. // SoTimeout读超时,服务端flush到输出流的间隔时间,也就是服务端多久时间内必须flush(或者close)一次到输出流。
  8. // 传输数据不会发送一个数据包,SoTimeout不是指整个传输时间,而是指两个数据包之间的间隔时间。
  9. ftpClient.setDefaultTimeout(10000);//传输控制命令的SoTimeout,一个命令等待响应结果的超时时间,单位毫秒
  10. ftpClient.setDataTimeout(10000);//传输数据的SoTimeout,单位毫秒
  11. //下面2个一般成对出现
  12. ftpClient.setControlKeepAliveTimeout(60);//传输数据这个过程中,传输控制命令的心跳(保活)时间,单位秒,tcp网络编程中一般设置心跳为300
  13. ftpClient.setControlKeepAliveReplyTimeout(10000);//传输数据这个过程中,暂时替换掉传输控制命令的SoTimeout,单位毫秒
  14. ftpClient.connect(ip, port); // 连接ftp服务器
  15. ftpClient.login(username, password); // 登录ftp服务器
  16. ftpClient.setRemoteVerificationEnabled(false);//取消服务器获取自身Ip地址和提交的host进行匹配,否则当不一致时报出以上异常。
  17. ftpClient.enterLocalPassiveMode();//被动模式,PASV模式。通知服务器打开一个数据端口,客户端将连接到这个端口进行数据传输。
  18. ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
  19. ftpClient.setBufferSize(1024);
  20. int replyCode = ftpClient.getReplyCode(); // 是否成功登录服务器
  21. if (FTPReply.isPositiveCompletion(replyCode)) {
  22. logger.info("连接成功...ftp服务器:" + ip + ":" + port);
  23. return true;
  24. }
  25. ftpClient.setSoTimeout(10000);//同setDefaultTimeout,会覆盖setDefaultTimeout,单位毫秒,这个参数要连接成功以后设置,否则报错空指针异常
  26. logger.info("连接失败...ftp服务器:" + ip + ":" + port);
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. logger.error(e.getMessage(), e);
  30. }
  31. return false;
  32. }

梳理之后,FTPClient 一共有 6 个设置超时的接口,而不管是文件上传或下载,这过程,FTP 都会创建两个 Socket,一个用于传输控制命令,一个用于传输文件数据,超时接口和这两个 Socket 之间的关系如下:

setConnectTimeout() 用于设置终端 Socket 与 FTP 服务器建立连接这个过程的超时时间。
setDefaultTimeout() 用于设置终端的传输控制命令的 Socket 的 SoTimeout,即针对传输控制命令的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
setSoTimeout() 作用跟上个方法一样,区别仅在于该方法设置的超时会覆盖掉上个方法设置的值。
setDataTimeout() 用于设置终端的传输数据的 Socket 的 Sotimeout,即针对传输文件数据的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
setControlKeepAliveTimeout() 用于设置当处于传输数据过程中,按指定的时间阈值定期让传输控制命令的 Socket 发送一个无操作命令 NOOP 给服务器,让它 keep alive。
setControlKeepAliveReplyTimeout():只有调用上个方法后,该方法才能生效,用于设置在传输数据这个过程中,暂时替换掉传输控制命令的 Socket 的 SoTimeout,传输过程结束恢复这个 Socket 原本的 SoTimeout。


 

参考:

查看ftp是否存在阻塞_记录 FTPClient 超时处理的相关问题_weixin_39906130的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/255526
推荐阅读
  

闽ICP备14008679号