设为首页 收藏本站
查看: 1029|回复: 0

[经验分享] 定时上传FTP文件

[复制链接]

尚未签到

发表于 2016-6-8 08:20:16 | 显示全部楼层 |阅读模式
这两天搞了一个定时上传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()。
我在上传下载文件的过程中就是少了这么一句,查问题花了不少功夫。
问题的症状:上传的文件在FTP服务器上生成了,但是没有内容;再看程序卡在ftp.storeFile(remote, input);不走了,也不报异常(个人认为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传输有两种模式:主动模式(PORT)和被动模式(PASV)
主动模式:客户端主动连服务器端;端口用20
被动模式:服务器端连客户端;随机打开一个高端端口(端口号大于1024)
小提示:有防火墙用户不能使用主动模式,这是因为防火墙不允许来自网外的主动连接,所以用户必须同使用被动模式。
到这里上面遇到的问题也就比较清晰了。
http://www.xiaojb.com/archives/it/ftp.shtml
这个链接有一个比较完整的FTP交互流程,简单易懂

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-227602-1-1.html 上篇帖子: edtFtp实现FTP工具类 下篇帖子: FTP安装及设置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表