commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sebb (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (NET-584) Error with org.apache.commons.net.ftp.FTPClient
Date Sat, 11 Mar 2017 10:06:04 GMT

    [ https://issues.apache.org/jira/browse/NET-584?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15906152#comment-15906152
] 

Sebb commented on NET-584:
--------------------------

The NOOPs are only (potentially) needed for long running data transfers which pass through
a router.
They should not be needed for talking directly to an FTP server, because the server knows
which control channels are associated with which data channels.
(If it does not, it is badly broken!)

Some routers are clever enough to do the same; some just see an idle channel and assume it
has been abandoned. These latter need NOOPs to try and prevent disconnection.

FTPClient only sends the NOOPs if the wait time is > 0 and the command is one of the retrieve/store
operations that don't involve application interaction.

In other cases where the control channel may be idle for long periods, it is up to the app
to send NOOPs.

FTP servers that can support parallel control channel traffic will respond to the NOOPs during
the data transfer.
If not, then the replies will likely be sent when the transfer completes and the server returns
to processing the control channel.
FTPClient keeps a count of the number of unanswered NOOPs and tries to drain these at the
end of the transfer.
If any requests or responses got lost, then of course we get a timeout, which is what I think
we are seeing.
I guess the longer the data transfer, the more likely it is that they are lost. This may explain
the behaviour you are seeing with bigger files.

Note: the SNAPSHOT code now assumes that a timeout during cleanup means that there are no
more replies left and does not throw an exception (it writes to stderr instead).

I think it is correct to ignore the timeout here; however writing to stderr is no use for
production code.
Need to either ignore the timeout or find a way to let the app know (or a way for the app
to find out).

Meanwhile it would be very helpful if you were able to try the updated code.

> Error with org.apache.commons.net.ftp.FTPClient 
> ------------------------------------------------
>
>                 Key: NET-584
>                 URL: https://issues.apache.org/jira/browse/NET-584
>             Project: Commons Net
>          Issue Type: Bug
>          Components: FTP
>            Reporter: Kazantsev Andrey Sergeevich
>
> I have a question about using library commons-net-3.4.jar
> Question is about org.apache.commons.net.ftp.FTPClient method setControlKeepAliveTimeout.
> Read about using it on:
> https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html
> When I use it in my code I get this error:
> {code}
> java.net.SocketTimeoutException: Read timed out
> 	at java.net.SocketInputStream.socketRead0(Native Method)
> 	at java.net.SocketInputStream.read(SocketInputStream.java:163)
> 	at java.net.SocketInputStream.read(SocketInputStream.java:133)
> 	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:322)
> 	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:364)
> 	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:210)
> 	at java.io.InputStreamReader.read(InputStreamReader.java:205)
> 	at java.io.BufferedReader.fill(BufferedReader.java:165)
> 	at java.io.BufferedReader.read(BufferedReader.java:186)
> 	at org.apache.commons.net.io.CRLFLineReader.readLine(CRLFLineReader.java:58)
> 	at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:313)
> 	at org.apache.commons.net.ftp.FTP.__getReplyNoReport(FTP.java:303)
> 	at org.apache.commons.net.ftp.FTPClient$CSL.cleanUp(FTPClient.java:3838)
> 	at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:695)
> 	at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:643)
> 	at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:2033)
> 	at ru.mdm.File.Transfer.FTP.PutRemoteFileBinary(FTP.java:192)
> 	at ru.mdm.File.Transfer.TimeLimit.Thread.Protocol.PutRemoteFileBinaryThread.actionsToExecute(PutRemoteFileBinaryThread.java:23)
> 	at ru.mdm.File.Transfer.TimeLimit.OperationThread.run(OperationThread.java:60)
> {code}
> Without enabling this option all works fine.
> Here is the code:
> {code}
> package ru.mdm.File.Transfer;
> import bin.ru.osa.common.utils.*;
> import java.util.List;
> import java.io.*;
> import com.ibm.broker.javacompute.MbJavaComputeNode;
> import com.ibm.broker.plugin.*;
> import org.apache.commons.net.ftp.*;
> import org.apache.commons.net.*;
> import ru.mdm.File.Transfer.Options.OptionsXMLProcessor;
> public class FTP implements Protocol 
> {
> 	
> 	FTPClient client = new FTPClient();
> 	
> 	OptionsXMLProcessor optionsXMLProcessor;
> 	
> 	
> 	boolean   st;
> 	String LastMessage = new String();
> 	
> 	boolean   ignoreErrors = false;
> 	
> 	
> 	public FTP() 
> 	{
> 		super();		
> 	}
> 	
> 	protected void finalize() { disconnect(); }
> 	
> 	public void connect(String CntName, 
> 						String Host, 
> 						String Port, 
> 						String L, 
> 						String P)  throws Exception
> 	{
> 	  try
> 	  {		
> 		client.setControlKeepAliveTimeout(300);
> 	    client.connect(Host);
> 	    client.login(L, P);
> 	    CheckState();	    
> 	  }
> 	  catch(Exception e)
> 	  {
> 	     LastMessage=client.getReplyString();	     	     
> 	     if(LastMessage == null) LastMessage = e.getMessage();
> 	     
> 	     e.printStackTrace();
> 	     
> 		 throw e;
> 	  }
> 	}	
> 	
> 	public void disconnect()
> 	{
> 		try
> 		{
> 			if(client.isConnected())
> 			{
> 				client.logout();  
> 				client.disconnect();
> 			}
> 		}
> 		catch(Exception e)
> 		{			
> 			e.printStackTrace();
> 		}
> 	}	
> 	
> 	public void chmod(String RemoteFile, String Rights)  throws Exception
> 	{
> 		client.sendSiteCommand("chmod "+RemoteFile+" "+Rights);
> 		CheckState();
> 	}
> 	
> 	
> 	public void lsMB(MbElement InputDir,MbElement filelist)   throws Exception, MbException
> 	{
> 		MbElement xfile;		
> 		
> 		for (FTPFile file : client.listFiles((String)InputDir.evaluateXPath("string(SOURCE_PATH)")))
>         {
>           if(!file.isFile()) continue; //-- No sub-dirs, No Symlinks !	             
        
>           
>           xfile=filelist.createElementAsLastChild(MbElement.TYPE_NAME, "File", null);
>           xfile.createElementAsLastChild(MbElement.TYPE_NAME, "FileName", file.getName());
>           xfile.createElementAsLastChild(MbElement.TYPE_NAME, "FileSize", file.getSize());
>           xfile.createElementAsLastChild(MbElement.TYPE_NAME, "SourcePath", (String)InputDir.evaluateXPath("string(SOURCE_PATH)"));
>           xfile.createElementAsLastChild(MbElement.TYPE_NAME, "SourceGateway", (String)InputDir.evaluateXPath("string(GATEWAY_NAME)"));
>         }		
> 	}
> 	
> 	public void mkdir(String RemotePath)   throws Exception
> 	{
> 	   client.makeDirectory(RemotePath);
> 	   CheckState();
> 	}
> 	
> 	public void chdir(String RemotePath)   throws Exception
> 	{
> 		client.changeWorkingDirectory(RemotePath);	
> 		CheckState();
> 	}
> 	
> 	public void delete(String RemotePath)   throws Exception
> 	{
> 		client.deleteFile(RemotePath);	
> 		CheckState();
> 	}
> 	
> 	
> 		
> 	public void rename(String RemoteFileSrc, String RemoteFileDst)    throws Exception
> 	{
> 	     client.rename(RemoteFileSrc, RemoteFileDst);
> 	     CheckState();
> 	}
> 	
> 		
>    public void GetRemoteFileBinary(String RemoteFile, String LocalFile)     throws Exception
>    {
> 	   client.enterLocalPassiveMode();
>        client.setFileType(FTPClient.BINARY_FILE_TYPE);
>        client.retrieveFile(RemoteFile, 
>      		               new FileOutputStream(LocalFile));
>        
>        
>        CheckState();
>     }
>   		
>    public void PutRemoteFileBinary(String LocalFile, String RemoteFile)      throws Exception
>    {
>        client.enterLocalPassiveMode();
>        client.setFileType(FTPClient.BINARY_FILE_TYPE);
>        client.storeFile(RemoteFile, 
>     		            new FileInputStream(LocalFile));	
>        CheckState();
>    }   
>    
>    
> 	public void ignoreErrors(boolean x)  { ignoreErrors=x;	}
>    
> 	
> 	public boolean isOK()  { return st;	}
> 	
> 	public boolean isConnected()	
> 	{
> 		boolean answer=false;
> 		try {
> 			answer = client.sendNoOp();
> 		} catch (IOException e) {
> 			// TODO Auto-generated catch block
> 			e.printStackTrace();
> 		}		
> 		st = answer;
> 		return answer;		
>        
> 	}
> 	
> 	
> 	public String LastMessage() {	return LastMessage;	};
> 	
> 	
> 	public void CheckState(boolean state) throws Exception
> 	{
> 	    int reply = client.getReplyCode();
>         if(FTPReply.isPositiveCompletion(reply))    st=true;
>         else                                        st=false;
> 		
>         LastMessage=client.getReplyString();	
> 		
> 		if(!st && !ignoreErrors)	
> 			throw new Exception(LastMessage);
> 	}
> 	
> 	public void CheckState() throws Exception
> 	{
> 	    int reply = client.getReplyCode();
>         if(FTPReply.isPositiveCompletion(reply))    st=true;
>         else                                        st=false;
> 		
>         LastMessage=client.getReplyString();	
> 		
> 		if(!st && !ignoreErrors)	
> 			throw new Exception(LastMessage);
> 	}
> 	
> 	public void attachOptions(OptionsXMLProcessor optionsXMLProcessor) throws Exception

> 	{
> 		this.optionsXMLProcessor = optionsXMLProcessor;
> 	}
> 	
> 	public String getIP() {
> 		
> 		return "";
> 	}
> 	
> 	public boolean isIgnoreErrors() 
> 	{		
> 		return ignoreErrors;
> 	}
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Mime
View raw message