定时上传FTP文件

这两天搞了一个定时上传FTP文件的小功能模块。
其中FTP上传下载用的是apache的org.apache.commons.net包中的FTPClient类实现的;这个东西用起来还是相当方便的。
下面是apach自带的FTPExample的类,现在把源代码贴出来,供大家参考:
/***略掉了包和import的说明部分***/
043 public final class FTPExample
044 {
045
046 public static final String USAGE =
047 "Usage: ftp [-s] [-b] <hostname> <username> <password> <remote file> <local file>\n" +
048 "\nDefault behavior is to download a file and use ASCII transfer mode.\n" +
049 "\t-s store file on server (upload)\n" +
050 "\t-b use binary transfer mode\n";
051
052 public static final void main(String[] args)
053 {
054 int base = 0;
055 boolean storeFile = false, binaryTransfer = false, error = false;
056 String server, username, password, remote, local;
057 FTPClient ftp;
058
059 for (base = 0; base < args.length; base++)
060 {
061 if (args[base].startsWith("-s"))
062 storeFile = true;
063 else if (args[base].startsWith("-b"))
064 binaryTransfer = true;
065 else
066 break;
067 }
068
069 if ((args.length - base) != 5)
070 {
071 System.err.println(USAGE);
072 System.exit(1);
073 }
074
075 server = args[base++];
076 username = args[base++];
077 password = args[base++];
078 remote = args[base++];
079 local = args[base];
080
081 ftp = new FTPClient();
082 ftp.addProtocolCommandListener(new PrintCommandListener(
083 new PrintWriter(System.out)));
084
085 try
086 {
087 int reply;
088 ftp.connect(server);
089 System.out.println("Connected to " + server + ".");
090
091 // After connection attempt, you should check the reply code to verify
092 // success.
093 reply = ftp.getReplyCode();
094
095 if (!FTPReply.isPositiveCompletion(reply))
096 {
097 ftp.disconnect();
098 System.err.println("FTP server refused connection.");
099 System.exit(1);
100 }
101 }
102 catch (IOException e)
103 {
104 if (ftp.isConnected())
105 {
106 try
107 {
108 ftp.disconnect();
109 }
110 catch (IOException f)
111 {
112 // do nothing
113 }
114 }
115 System.err.println("Could not connect to server.");
116 e.printStackTrace();
117 System.exit(1);
118 }
119
120 __main:
121 try
122 {
123 if (!ftp.login(username, password))
124 {
125 ftp.logout();
126 error = true;
127 break __main;
128 }
129
130 System.out.println("Remote system is " + ftp.getSystemName());
131
132 if (binaryTransfer)
133 ftp.setFileType(FTP.BINARY_FILE_TYPE);
134
135 // Use passive mode as default because most of us are
136 // behind firewalls these days.
137 ftp.enterLocalPassiveMode();
138
139 if (storeFile)
140 {
141 InputStream input;
142
143 input = new FileInputStream(local);
144
145 ftp.storeFile(remote, input);
146
147 input.close();
148 }
149 else
150 {
151 OutputStream output;
152
153 output = new FileOutputStream(local);
154
155 ftp.retrieveFile(remote, output);
156
157 output.close();
158 }
159
160 ftp.logout();
161 }
162 catch (FTPConnectionClosedException e)
163 {
164 error = true;
165 System.err.println("Server closed connection.");
166 e.printStackTrace();
167 }
168 catch (IOException e)
169 {
170 error = true;
171 e.printStackTrace();
172 }
173 finally
174 {
175 if (ftp.isConnected())
176 {
177 try
178 {
179 ftp.disconnect();
180 }
181 catch (IOException f)
182 {
183 // do nothing
184 }
185 }
186 }
187
188 System.exit(error ? 1 : 0);
189 } // end main
190
191 }

中间遇见的问题:
代码中第137行ftp.enterLocalPassiveMode();
在api中的解释为:
Set the current data connection mode to PASSIVE_LOCAL_DATA_CONNECTION_MODE . Use this method only for data transfers between the client and server. This method causes a PASV command to be issued to the server before the opening of every data connection, telling the server to open a data port to which the client will connect to conduct data transfers. The FTPClient will stay in PASSIVE_LOCAL_DATA_CONNECTION_MODE until the mode is changed by calling some other method such as enterLocalActiveMode()。

我在上传下载文件的过程中就是少了这么一句,查问题花了不少功夫。
问题的症状:[color=red]上传的文件在FTP服务器上生成了,但是没有内容[/color];再看程序卡在ftp.storeFile(remote, input);不走了,[color=red]也不报异常[/color](个人认为apache这里搞的不好,多少提示一下吗,一点反应都没有)。
经过:最初我没有加第137行这句,然后在本机启了一个FTP服务,上传下载都OK。再在内网的一个测试机上测试,也OK。放到正式环境上,就出现了我上面说的症状。到现在我也没明白为什么。希望能有高人指点迷津。

然后我查了api相关的几个方法enterLocalActiveMode,enterRemoteActiveMode,enterRemotePassiveMode。
我的理解大概是这样的
enterLocalPassiveMode:设置客户端PASV模式
static int PASSIVE_LOCAL_DATA_CONNECTION_MODE
enterLocalActiveMode:设置客户端PORT模式
static int ACTIVE_LOCAL_DATA_CONNECTION_MODE
enterRemoteActiveMode:server to server
static int ACTIVE_REMOTE_DATA_CONNECTION_MODE
requiring the one(client) connect to the other server's data port to initiate a data transfer.
enterRemotePassiveMode:server to server
static int PASSIVE_REMOTE_DATA_CONNECTION_MODE
requiring the other server to connect to the first server's data port to initiate a data transfer

对FTP协议了解的不太清楚是一个很大的原因,有时间要看看FTP协议的内容了。

查了一些资料:
FTP传输有两种模式:[color=blue]主动模式(PORT)和被动模式(PASV)[/color]
主动模式:客户端主动连服务器端;端口用20
被动模式:服务器端连客户端;随机打开一个高端端口(端口号大于1024)

[b]小提示[/b]:有防火墙用户不能使用主动模式,这是因为防火墙不允许来自网外的主动连接,所以用户必须同使用被动模式。

到这里上面遇到的问题也就比较清晰了。

http://www.xiaojb.com/archives/it/ftp.shtml
这个链接有一个比较完整的FTP交互流程,简单易懂
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值