基于socket通信实现Ftp连接

FTP 概述

文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用。FTP的目标是提高文件的共享性和可靠高效地传送数据。

在传输文件时,FTP 客户端程序先与服务器建立连接,然后向服务器发送命令。服务器收到命令后给予响应,并执行命令。FTP 协议与操作系统无关,任何操作系统上的程序只要符合 FTP 协议,就可以相互传输数据。本文主要基于 LINUX 平台,对 FTP 客户端的实现原理进行详尽的解释并阐述如何使用 C 语言编写一个简单的 FTP 客户端。

FTP 协议

相比其他协议,如 HTTP 协议,FTP 协议要复杂一些。与一般的 C/S 应用不同点在于一般的C/S 应用程序一般只会建立一个 Socket 连接,这个连接同时处理服务器端和客户端的连接命令和数据传输。而FTP协议中将命令与数据分开传送的方法提高了效率。

FTP 使用 2 个端口,一个数据端口和一个命令端口(也叫做控制端口)。这两个端口一般是21 (命令端口)和 20 (数据端口)。控制 Socket 用来传送命令,数据 Socket 是用于传送数据。每一个 FTP 命令发送之后,FTP 服务器都会返回一个字符串,其中包括一个响应代码和一些说明信息。其中的返回码主要是用于判断命令是否被成功执行了。

命令端口

一般来说,客户端有一个 Socket 用来连接 FTP 服务器的相关端口,它负责 FTP 命令的发送和接收返回的响应信息。一些操作如“登录”、“改变目录”、“删除文件”,依靠这个连接发送命令就可完成。

数据端口

对于有数据传输的操作,主要是显示目录列表,上传、下载文件,我们需要依靠另一个 Socket来完成。

如果使用被动模式,通常服务器端会返回一个端口号。客户端需要用另开一个 Socket 来连接这个端口,然后我们可根据操作来发送命令,数据会通过新开的一个端口传输。

如果使用主动模式,通常客户端会发送一个端口号给服务器端,并在这个端口监听。服务器需要连接到客户端开启的这个数据端口,并进行数据的传输。

下面对 FTP 的主动模式和被动模式做一个简单的介绍。

主动模式 (PORT)

主动模式下,客户端随机打开一个大于 1024 的端口向服务器的命令端口 P,即 21 端口,发起连接,同时开放N +1 端口监听,并向服务器发出 “port N+1” 命令,由服务器从它自己的数据端口 (20) 主动连接到客户端指定的数据端口 (N+1)。

FTP 的客户端只是告诉服务器自己的端口号,让服务器来连接客户端指定的端口。对于客户端的防火墙来说,这是从外部到内部的连接,可能会被阻塞。

被动模式 (PASV)

为了解决服务器发起到客户的连接问题,有了另一种 FTP 连接方式,即被动方式。命令连接和数据连接都由客户端发起,这样就解决了从服务器到客户端的数据端口的连接被防火墙过滤的问题。

被动模式下,当开启一个 FTP 连接时,客户端打开两个任意的本地端口 (N > 1024 和 N+1) 。

第一个端口连接服务器的 21 端口,提交 PASV 命令。然后,服务器会开启一个任意的端口 (P > 1024 ),返回如“227 entering passive mode (127,0,0,1,4,18)”。 它返回了 227 开头的信息,在括号中有以逗号隔开的六个数字,前四个指服务器的地址,最后两个,将倒数第二个乘 256 再加上最后一个数字,这就是 FTP 服务器开放的用来进行数据传输的端口。如得到 227 entering passive mode (h1,h2,h3,h4,p1,p2),那么端口号是 p1*256+p2,ip 地址为h1.h2.h3.h4。这意味着在服务器上有一个端口被开放。客户端收到命令取得端口号之后, 会通过 N+1 号端口连接服务器的端口 P,然后在两个端口之间进行数据传输。

主要用到的 FTP 命令

FTP 每个命令都有 3 到 4 个字母组成,命令后面跟参数,用空格分开。每个命令都以 "\r\n"结束。

要下载或上传一个文件,首先要登入 FTP 服务器,然后发送命令,最后退出。这个过程中,主要用到的命令有 USER、PASS、SIZE、REST、CWD、RETR、PASV、PORT、QUIT。

USER: 指定用户名。通常是控制连接后第一个发出的命令。“USER gaoleyi\r\n”: 用户名为gaoleyi 登录。

PASS: 指定用户密码。该命令紧跟 USER 命令后。“PASS gaoleyi\r\n”:密码为 gaoleyi。

SIZE: 从服务器上返回指定文件的大小。“SIZE file.txt\r\n”:如果 file.txt 文件存在,则返回该文件的大小。

CWD: 改变工作目录。如:“CWD dirname\r\n”。

PASV: 让服务器在数据端口监听,进入被动模式。如:“PASV\r\n”。

PORT: 告诉 FTP 服务器客户端监听的端口号,让 FTP 服务器采用主动模式连接客户端。如:“PORT h1,h2,h3,h4,p1,p2”。

RETR: 下载文件。“RETR file.txt \r\n”:下载文件 file.txt。

STOR: 上传文件。“STOR file.txt\r\n”:上传文件 file.txt。

REST: 该命令并不传送文件,而是略过指定点后的数据。此命令后应该跟其它要求文件传输的 FTP 命令。“REST 100\r\n”:重新指定文件传送的偏移量为 100 字节。

QUIT: 关闭与服务器的连接。

FTP 响应码

客户端发送 FTP 命令后,服务器返回响应码。

响应码用三位数字编码表示:

第一个数字给出了命令状态的一般性指示,比如响应成功、失败或不完整。

第二个数字是响应类型的分类,如 2 代表跟连接有关的响应,3 代表用户认证。

第三个数字提供了更加详细的信息。

第一个数字的含义如下:

1 表示服务器正确接收信息,还未处理。

2 表示服务器已经正确处理信息。

3 表示服务器正确接收信息,正在处理。

4 表示信息暂时错误。

5 表示信息永久错误。

第二个数字的含义如下:

0 表示语法。

1 表示系统状态和信息。

2 表示连接状态。

3 表示与用户认证有关的信息。

4 表示未定义。

5 表示与文件系统有关的信息。

Socket 编程的几个重要步骤

Socket 客户端编程主要步骤如下:

  1. socket() 创建一个 Socket
  2. connect() 与服务器连接
  3. write() 和 read() 进行会话
  4. close() 关闭 Socket

Socket 服务器端编程主要步骤如下:

  1. socket() 创建一个 Socket
  2. bind()
  3. listen() 监听
  4. accept() 接收连接的请求
  5. write() 和 read() 进行会话
  6. close() 关闭 Socket

实现 FTP 客户端上传下载功能

下面让我们通过一个例子来对 FTP 客户端有一个深入的了解。本文实现的 FTP 客户端有下列功能:

  1. 客户端和 FTP 服务器建立 Socket 连接。
  2. 向服务器发送 USER、PASS 命令登录 FTP 服务器。
  3. 使用 PASV 命令得到服务器监听的端口号,建立数据连接。
  4. 使用 RETR/STOR 命令下载/上传文件。
  5. 在下载完毕后断开数据连接并发送 QUIT 命令退出。

示例代码:

1.FTP连接

[java]  view plain  copy
  1. public void connectFtp() {  
  2.         try {  
  3.             mFtpClient = new Socket(Config.FTP.HOST_IP, Config.FTP.HOST_PORT);  
  4.             mReader = new BufferedReader(new InputStreamReader(mFtpClient.getInputStream()));  
  5.             mWriter = new BufferedWriter(new OutputStreamWriter(mFtpClient.getOutputStream()));  
  6.   
  7.             sendCommand("USER " + Config.FTP.FTP_USERNAME);  
  8.             sendCommand("PASS " + Config.FTP.FTP_PASSWD);  
  9.         } catch (IOException e) {  
  10.             e.printStackTrace();  
  11.         }  
  12.     }  

2.向FTP服务器发送命令

[java]  view plain  copy
  1. private void sendCommand(String command) throws IOException {  
  2.         if (Tools.StringTools.isEmpty(command)) {  
  3.             return;  
  4.         }  
  5.   
  6.         if (mFtpClient == null) {  
  7.             return;  
  8.         }  
  9.   
  10.         mWriter.write(command + "\r\n");  
  11.         mWriter.flush();  
  12.     }  

3.向FTP服务器上传文件

[java]  view plain  copy
  1. public void uploadFile(String localPath, String ftpPath) throws IOException {  
  2.         // 进入被动模式  
  3.         sendCommand("PASV");  
  4.   
  5.         // 获得ip和端口  
  6.         String response = readNewMessage();  
  7.         String[] ipPort = getIPPort(response);  
  8.         String ip = ipPort[0];  
  9.         int port = Integer.parseInt(ipPort[1]);  
  10.   
  11.         // 建立数据端口的连接  
  12.         Socket dataSocket = new Socket(ip, port);  
  13.         sendCommand("STOR " + ftpPath);  
  14.   
  15.         // 上传文件前的准备  
  16.         File localFile = new File(localPath);  
  17.         OutputStream outputStream = dataSocket.getOutputStream();  
  18.         FileInputStream fileInputStream = new FileInputStream(localFile);  
  19.   
  20.         // 上传文件  
  21.         int offset;  
  22.         byte[] bytes = new byte[1024];  
  23.         while ((offset = fileInputStream.read(bytes)) != -1) {  
  24.             outputStream.write(bytes, 0, offset);  
  25.         }  
  26.         System.out.println("upload success!!");  
  27.   
  28.         // 上传文件后的善后工作  
  29.         outputStream.close();  
  30.         fileInputStream.close();  
  31.         dataSocket.close();  
  32.     }  

4.从FTP服务器下载文件

[java]  view plain  copy
  1. public void downloadFile(String localPath, String ftpPath) throws IOException {  
  2.         // 进入被动模式  
  3.         sendCommand("PASV");  
  4.   
  5.         // 获得ip和端口  
  6.         String response = readNewMessage();  
  7.         String[] ipPort = getIPPort(response);  
  8.         String ip = ipPort[0];  
  9.         int port = Integer.parseInt(ipPort[1]);  
  10.   
  11.         // 建立数据端口的连接  
  12.         Socket dataSocket = new Socket(ip, port);  
  13.         sendCommand("RETR " + ftpPath);  
  14.   
  15.         // 下载文件前的准备  
  16.         File localFile = new File(localPath);  
  17.         InputStream inputStream = dataSocket.getInputStream();  
  18.         FileOutputStream fileOutputStream = new FileOutputStream(localFile);  
  19.   
  20.         // 下载文件  
  21.         int offset;  
  22.         byte[] bytes = new byte[1024];  
  23.         while ((offset = inputStream.read(bytes)) != -1) {  
  24.             fileOutputStream.write(bytes, 0, offset);  
  25.         }  
  26.         System.out.println("download success!!");  
  27.   
  28.         // 下载文件后的善后工作  
  29.         inputStream.close();  
  30.         fileOutputStream.close();  
  31.         dataSocket.close();  
  32.     }  

5.断开FTP服务器连接

[java]  view plain  copy
  1. public void disconnectFtp() {  
  2.         if (mFtpClient == null) {  
  3.             return;  
  4.         }  
  5.   
  6.         if (!mFtpClient.isConnected()) {  
  7.             return;  
  8.         }  
  9.   
  10.         try {  
  11.             mFtpClient.close();  
  12.         } catch (IOException e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  

参考自https://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/

          http://blog.csdn.net/lemon_tree12138/article/details/49777467

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于GUI的FTP客户端的实现可以使用Java语言来编写。首先,需要使用Java的Swing或JavaFX库来创建用户界面。然后,需要使用Java的网络编程功能来实现FTP协议的功能。 在用户界面部分,可以使用Swing或JavaFX创建一个窗口,包含文件列表、上传按钮、下载按钮和连接按钮等组件。文件列表可以使用JTable或ListView来展示远程服务器上的文件列表。 连接按钮的点击事件可以触发一个方法,该方法通过使用Java的Socket类来建立与FTP服务器的连接连接成功后,可以使用Socket发送FTP命令和接收服务器的响应。 上传按钮的点击事件可以触发一个方法,该方法通过Socket发送STOR命令来将本地文件上传到服务器。可以通过文件选择对话框来选择要上传的文件。上传过程中可以显示上传的进度条和状态信息。 下载按钮的点击事件可以触发一个方法,该方法通过Socket发送RETR命令来从服务器下载文件到本地。可以通过选择需要下载的文件,然后选择本地存储路径。下载过程中也可以显示下载的进度条和状态信息。 另外,还可以添加其他功能,如创建目录、删除文件等。这些功能可以通过发送不同的FTP命令来实现。 需要注意的是,FTP协议的实现可能涉及一些网络编程的知识,如处理socket连接、解析FTP响应等。同时,要保证在进行网络操作时要在子线程中执行,避免阻塞界面的用户交互。 总之,基于GUI的FTP客户端的实现需要结合Java的网络编程和Swing或JavaFX的界面设计来完成。这样用户就可以通过直观友好的界面来方便地上传下载文件和管理FTP服务器。 ### 回答2: 基于GUI的FTP客户端的实现可以使用Java编程语言来实现。下面是一个简单的300字的回答: 基于GUI的FTP客户端的实现需要使用Java的网络编程API,比如使用Java的Socket类来建立和FTP服务器的连接。可以使用Swing框架来创建用户界面,通过用户界面可以输入FTP服务器的地址、用户名和密码等信息,然后通过点击按钮来执行相应的FTP操作。 首先,我们需要创建一个主窗口,用户可以在该窗口中输入FTP服务器的地址、用户名和密码。然后,我们可以使用Java的Socket类来与FTP服务器建立连接,并通过FTP协议发送命令进行文件传输。 在界面中,我们可以使用一些按钮来执行不同的FTP操作,比如上传文件、下载文件、删除文件等。对于上传和下载操作,我们需要选择本地文件和服务器文件的路径,并通过Socket类来发送和接收文件数据。 另外,我们可以使用Swing的JList组件来显示FTP服务器中的文件列表,并通过选择文件来执行相应的操作。通过监听器来响应用户的操作,并使用Socket类来发送FTP命令。 为了提高用户体验,我们可以使用多线程来执行FTP传输操作,这样可以使得界面在文件传输过程中仍然响应用户的操作。 总之,基于GUI的FTP客户端的实现可以结合Java的网络编程API和Swing框架,通过用户界面和FTP协议实现用户与FTP服务器的交互,实现文件的上传、下载和删除等操作。 ### 回答3: 基于GUI的FTP客户端的实现需要使用Java编程语言。首先需要导入Java中的相关网络编程库,如java.net和java.io,以实现与服务器的通信和文件传输。其次,需要使用Java的图形用户界面库,如Swing或JavaFX来构建用户界面。 在开始编写代码前,需要先准备好一个GUI界面,其中包括连接服务器的IP地址和端口号的输入框、登录用户名和密码的输入框、显示文件列表的区域、上传和下载文件的按钮等。 在代码中,首先需要创建一个FTP客户端对象,其中包含连接服务器、登录、上传、下载等各种操作的方法。在连接服务器时,需要获取用户输入的IP地址和端口号,并使用Java的Socket类进行连接。登录时,需要获取用户输入的用户名和密码,并使用FTP协议的USER和PASS命令进行验证。 在获取文件列表时,可以使用FTP协议的LIST命令获取服务器上的文件列表,并将其显示在GUI界面上。在上传和下载文件时,可以使用FTP协议的STOR和RETR命令进行文件传输。 通过在GUI界面上添加事件监听器,可以实现用户在点击按钮时触发相应的操作。例如,在点击上传按钮时,调用FTP客户端对象的上传方法,将用户选择的文件上传到服务器。 最后,需要注意处理异常情况,如无法连接服务器、登录失败、文件传输中断等。可以在代码中使用异常处理机制来捕获并处理这些异常,例如在连接服务器时捕获SocketException,登录时捕获FTPException等。在出现异常时,可以在GUI界面上显示相应的提示信息,以提醒用户出现了错误。 综上所述,基于GUI的FTP客户端的实现可以通过使用Java的网络编程和图形用户界面库来实现。通过创建FTP客户端对象并在GUI界面上添加按钮等控件,可以实现FTP服务器的连接、登录、文件上传和下载等操作。同时,也需要适当处理异常情况,以提高程序的稳定性和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值