1. 请解释一下FTP连接的命令及响应
FTP命令
命令 描述
ABOR 中断数据连接程序
ACCT <account> 系统特权帐号
ALLO <bytes> 为服务器上的文件存储器分配字节
APPE <filename> 添加文件到服务器同名文件
CDUP <dir path> 改变服务器上的父目录
CWD <dir path> 改变服务器上的工作目录
DELE <filename> 删除服务器上的指定文件
HELP <command> 返回指定命令信息
LIST <name> 如果是文件名列出文件信息,如果是目录则列出文件列表
MODE <mode> 传输模式(S=流模式,B=块模式,C=压缩模式)
MKD <directory> 在服务器上建立指定目录
NLST <directory> 列出指定目录内容
NOOP 无动作,除了来自服务器上的承认
PASS <password> 系统登录密码
PASV 请求服务器等待数据连接
PORT <address> IP 地址和两字节的端口 ID
PWD 显示当前工作目录
QUIT 从 FTP 服务器上退出登录
REIN 重新初始化登录状态连接
REST <offset> 由特定偏移量重启文件传递
RETR <filename> 从服务器上找回(复制)文件
RMD <directory> 在服务器上删除指定目录
RNFR <old path> 对旧路径重命名
RNTO <new path> 对新路径重命名
SITE <params> 由服务器提供的站点特殊参数
SMNT <pathname> 挂载指定文件结构
STAT <directory> 在当前程序或目录上返回信息
STOR <filename> 储存(复制)文件到服务器上
STOU <filename> 储存文件到服务器名称上
STRU <type> 数据结构(F=文件,R=记录,P=页面)
SYST 返回服务器使用的操作系统
TYPE <data type> 数据类型(A=ASCII,E=EBCDIC,I=binary)
USER <username>> 系统登录的用户名
FTP响应码
响应代码 解释说明
110 新文件指示器上的重启标记
120 服务器准备就绪的时间(分钟数)
125 打开数据连接,开始传输
150 打开连接
200 成功
202 命令没有执行
211 系统状态回复
212 目录状态回复
213 文件状态回复
214 帮助信息回复
215 系统类型回复
220 服务就绪
221 退出网络
225 打开数据连接
226 结束数据连接
227 进入被动模式(IP 地址、ID 端口)
230 登录因特网
250 文件行为完成
257 路径名建立
331 要求密码
332 要求帐号
350 文件行为暂停
421 服务关闭
425 无法打开数据连接
426 结束连接
450 文件不可用
451 遇到本地错误
452 磁盘空间不足
500 无效命令
501 错误参数
502 命令没有执行
503 错误指令序列
504 无效命令参数
530 未登录网络
532 存储文件需要帐号
550 文件不可用
551 不知道的页类型
552 超过存储分配
553 文件名不允许
2. ftp 250 和 226的区别
FTP连接过程中,提示530 Login authentication failed错误是因为填写错了ftp密码。
解决方法:
登陆客户中心,客户中心 > 会员中心 > 产品与服务(不同的主机提供商可能不同仅供参考)进入购买的那个套餐,下面有个登陆详情然后输入新密码就行了,这样ftp就可以用了。
FTP登录常见提示错误:
1.connected. waiting for response. 220 serv-u ftp server v4.0 for winsock ready...
user anonymous 530 sorry, no anonymous access allowed. quit
不允许匿名登录
2.connected. waiting for response. 220 serv-u ftp server v4.0 for winsock ready...
user test 331 user name okay, need password. pass xxxxxx 530 not logged in. quit 一般是密码输入错误时出现的信息。
3.connecting to xxx.xxx.xxx.xxx, port 21 error: connection timed out
这个表明对方未开机,也可能是对方不在能访问的范围内。可能小区的服务器检修中。
4.connecting to xxx.xxx.xxx.xxx port 21 error: connection refused
这个一般表明对方已开机,但未开启ftp服务(没有开serv-u),也可能为对方不提供在这个端口上的服务
5.connecting to xxx.xxx.xxx.xxx, port 21 connected. waiting for response. disconnected from server. connection attempt failed. waiting for retry...
出现极有可能是重试时间定的太短被服务器封了。
6.connecting to xxx.xxx.xxx.xxx, port 21 connected. waiting for response. user xxx
331 user name okay, need password pass xxxxxx 530 not logged in, unauthorized ip address. quit
没有登记ip,或者登记的ip和现在的不一样,重新登记即可。
7.227 entering passive mode (218,3,87,224,10,232) retr hfdx-tsoaf.sub.rar 550 sorry, insufficient credit for download - upload first.
传输已失败.传输队列已完成但流量不够了,重新购买。
3. ftp250瓦什么水平
业余水平。ftp是检定直行车等级水平的专业能力,一般世界级的自行车都具有至少360~400W以上的ftp能力,最顶尖的职业选手ftp在340~360w之间,业余的自行车选手的ftp通常是在250~320w附近,对于耐力自行车,铁人三项的选手来说通过锻炼提高ftp能力是最重要的。
4. 关于如何实现FTP上传或者下载带进度和速率的实现方法
在这里需要说明的是,该方式是通过其他代码进行改进的。 首先我们需要定义一个委托,用来实现传输过程中传递文件的总数,已完成的字节数和速度,方便客户端界面上调用。 public delegate void TransferProcess(long total,long finished,double speed); 调用代码就不举例了 接下来我们建立一个FTPClient类,该类基于socket和FTP协议实现了连接FTP服务,建立目录,上传文件,下载文件等主要方法。结构如下: 需要注意的是,我们需要定一个事件event TransferProcess OnTransferProcess;该事件在实例化FTPClient之后需要调用,这个事件对实现进度条和速率是非常重要的。为了实现速率我们还需要定义个公开的成员startTime(开始时间)。我们现在主要是看一下如何上传的。 /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { //连接服务器 if (!bConnected) { Connect(); } UpdateStatus = true; //建立socket连接 Socket socketData = CreateDataSocket(); //向FTP服务器发生存储命令 SendCommand("STOR " + Path.GetFileName(strFileName)); //如何服务器返回的信息不是我们所需要的,就抛出异常 if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4)); } //建立本地文件的数据流 FileStream input = new FileStream(strFileName, FileMode.Open); int iBytes = 0; long total = input.Length;//该成员主要记录文件的总字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 long finished = 0;//该成员主要记录已经传输完成的字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 double speed = 0;//记录传输的速率 while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0)//循环从本地数据流中读取数据到缓冲区 { //Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0);//将缓冲区的数据发送到FTP服务器 DateTime endTime = DateTime.Now;//每次发送数据的结束时间 TimeSpan ts = endTime - startTime;//计算每次发送数据的时间间隔 finished += iBytes;//计算完成的字节数. Console.WriteLine(ts.Milliseconds); //计算速率,注意finished是字节,所以需要换算冲K字节 if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } //这里是必不可少的,否则你无法实现进度条 //如果传输进度事件被实例化,而且从本地数据流中读取数据不是空的并完成的字节数也不为空的话,则实现委托. if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close();//当传输完成之后需要关闭数据流,以便下次访问. if (socketData.Connected) { socketData.Close();//关闭当前的socket } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } 上面代码中注释写得比较详细,这里就不再一一讲解了,关于下载中实现进度条和速率的问题可以参考以上代码进行修改. 完整的代码如下: using System; using System.net; using System.IO; using System.Text; using System.net.Sockets; namespace MMSEncoder { public delegate void TransferProcess(long total,long finished,double speed); /// /// FTP Client /// public class FTPClient { public event TransferProcess OnTransferProcess; public bool UpdateStatus = true; public DateTime startTime; private bool IsAbortConnect = false; #region 构造函数 /// /// 缺省构造函数 /// public FTPClient() { strRemoteHost = ""; strRemotePath = ""; strRemoteUser = ""; strRemotePass = ""; strRemotePort = 21; bConnected = false; } /// /// 构造函数 /// /// FTP服务器IP地址 /// 当前服务器目录 /// 登录用户账号 /// 登录用户密码 /// FTP服务器端口 public FTPClient(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort) { strRemoteHost = remoteHost; strRemotePath = remotePath; strRemoteUser = remoteUser; strRemotePass = remotePass; strRemotePort = remotePort; Connect(); } #endregion #region 登陆字段、属性 /// /// FTP服务器IP地址 /// private string strRemoteHost; public string RemoteHost { get { return strRemoteHost; } set { strRemoteHost = value; } } /// /// FTP服务器端口 /// private int strRemotePort; public int RemotePort { get { return strRemotePort; } set { strRemotePort = value; } } /// /// 当前服务器目录 /// private string strRemotePath; public string RemotePath { get { return strRemotePath; } set { strRemotePath = value; } } /// /// 登录用户账号 /// private string strRemoteUser; public string RemoteUser { set { strRemoteUser = value; } } /// /// 用户登录密码 /// private string strRemotePass; public string RemotePass { set { strRemotePass = value; } } /// /// 是否登录 /// private Boolean bConnected; public bool Connected { get { return bConnected; } } #endregion #region 链接 /// /// 建立连接 /// public void Connect() { //if (IsAbortConnect) throw new IOException("用户强制终止了FTP"); socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort); // 链接 try { socketControl.Connect(ep); } catch (Exception) { throw new IOException("无法连接到远程服务器!"); } // 获取应答码 ReadReply(); if (iReplyCode != 220) { DisConnect(); throw new IOException(strReply.Substring(4)); } // 登陆 SendCommand("USER " + strRemoteUser); if (!(iReplyCode == 331 || iReplyCode == 230)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } if (iReplyCode != 230) { SendCommand("PASS " + strRemotePass); if (!(iReplyCode == 230 || iReplyCode == 202)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } } bConnected = true; // 切换到初始目录 if (!string.IsNullOrEmpty(strRemotePath)) { ChDir(strRemotePath); } } /// /// 关闭连接 /// public void DisConnect() { if (socketControl != null) { SendCommand("QUIT"); } CloseSocketConnect(); } public void AbortConnect() { if (socketControl != null) { SendCommand("ABOR"); } IsAbortConnect = true; //CloseSocketConnect(); } #endregion #region 传输模式 /// /// 传输模式:二进制类型、ASCII类型 /// public enum TransferType { Binary, ASCII }; /// /// 设置传输模式 /// /// 传输模式 public void SetTransferType(TransferType ttType) { if (ttType == TransferType.Binary) { SendCommand("TYPE I");//binary类型传输 } else { SendCommand("TYPE A");//ASCII类型传输 } if (iReplyCode != 200) { throw new IOException(strReply.Substring(4)); } else { trType = ttType; } } /// /// 获得传输模式 /// /// 传输模式 public TransferType GetTransferType() { return trType; } #endregion #region 文件操作 /// /// 获得文件列表 /// /// 文件名的匹配字符串 /// public string[] Dir(string strMask) { // 建立链接 if (!bConnected) { Connect(); } //建立进行数据连接的socket Socket socketData = CreateDataSocket(); //传送命令 SendCommand("NLST " + strMask); //分析应答代码 if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226)) { throw new IOException(strReply.Substring(4)); } //获得结果 strMsg = ""; while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); strMsg += GB2312.GetString(buffer, 0, iBytes); if (iBytes < buffer.Length) { break; } } char[] seperator = { '
' }; string[] strsFileList = strMsg.Split(seperator); socketData.Close();//数据socket关闭时也会有返回码 if (iReplyCode != 226) { ReadReply(); if (iReplyCode != 226) { throw new IOException(strReply.Substring(4)); } } return strsFileList; } /// /// 获取文件大小 /// /// 文件名 /// 文件大小 public long GetFileSize(string strFileName) { if (!bConnected) { Connect(); } SendCommand("SIZE " + Path.GetFileName(strFileName)); long lSize = 0; if (iReplyCode == 213) { lSize = Int64.Parse(strReply.Substring(4)); } else { throw new IOException(strReply.Substring(4)); } return lSize; } /// /// 删除 /// /// 待删除文件名 public void Delete(string strFileName) { if (!bConnected) { Connect(); } SendCommand("DELE " + strFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件) /// /// 旧文件名 /// 新文件名 public void Rename(string strOldFileName, string strNewFileName) { if (!bConnected) { Connect(); } SendCommand("RNFR " + strOldFileName); if (iReplyCode != 350) { throw new IOException(strReply.Substring(4)); } // 如果新文件名与原有文件重名,将覆盖原有文件 SendCommand("RNTO " + strNewFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } #endregion #region 上传和下载 /// /// 下载一批文件 /// /// 文件名的匹配字符串 /// 本地目录(不得以\结束) public void Get(string strFileNameMask, string strFolder) { if (!bConnected) { Connect(); } string[] strFiles = Dir(strFileNameMask); foreach (string strFile in strFiles) { if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串 { if (strFile.LastIndexOf(".") > -1) { Get(strFile.Replace("\r", ""), strFolder, strFile.Replace("\r", "")); } } } } /// /// 下载一个文件 /// /// 要下载的文件名 /// 本地目录(不得以\结束) /// 保存在本地时的文件名 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName) { if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName; } if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName); st.Close(); } FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create); Socket socketData = CreateDataSocket(); SendCommand("RETR " + strRemoteFileName); if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); output.Write(buffer, 0, iBytes); if (iBytes <= 0) { break; } } output.Close(); if (socketData.Connected) { socketData.Close(); } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } } } /// /// 上传一批文件 /// /// 本地目录(不得以\结束) /// 文件名匹配字符(可以包含*和?) public void Put(string strFolder, string strFileNameMask) { string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask); foreach (string strFile in strFiles) { //strFile是完整的文件名(包含路径) Put(strFile); } } /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { if (!bConnected) { Connect(); } UpdateStatus = true; Socket socketData = CreateDataSocket(); SendCommand("STOR " + Path.GetFileName(strFileName)); if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4)); } FileStream input = new FileStream(strFileName, FileMode.Open); int iBytes = 0; long total = input.Length; long finished = 0; //DateTime startTime = DateTime.Now; double speed = 0; while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0) { Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0); DateTime endTime = DateTime.Now; TimeSpan ts = endTime - startTime; finished += iBytes; Console.WriteLine(ts.Milliseconds); if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close(); if (socketData.Connected) { socketData.Close(); } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } #endregion #region 目录操作 /// /// 创建目录 /// /// 目录名 public void MkDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("MKD " + strDirName); if (iReplyCode != 257) { throw new IOException(strReply.Substring(4)); } } /// /// 删除目录 /// /// 目录名 public void RmDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("RMD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 改变目录 /// /// 新的工作目录名 public void ChDir(string strDirName) { if (strDirName.Equals(".") || strDirName.Equals("")) { return; } if (!bConnected) { Connect(); } SendCommand("CWD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } this.strRemotePath = strDirName; } #endregion #region 内部变量 /// /// 服务器返回的应答信息(包含应答码) /// private string strMsg; /// /// 服务器返回的应答信息(包含应答码) /// private string strReply; /// /// 服务器返回的应答码 /// private int iReplyCode; /// /// 进行控制连接的socket /// private Socket socketControl; /// /// 传输模式 /// private TransferType trType; /// /// 接收和发送数据的缓冲区 /// private static int BLOCK_SIZE = Int16.MaxValue; Byte[] buffer = new Byte[BLOCK_SIZE]; /// /// 编码方式(为防止出现中文乱码采用 GB2312编码方式) /// Encoding GB2312 = Encoding.Default ;//Encoding.GetEncoding("gb2312"); #endregion #region 内部函数 /// /// 将一行应答字符串记录在strReply和strMsg /// 应答码记录在iReplyCode /// private void ReadReply() { strMsg = ""; strReply = ReadLine(); iReplyCode = Int32.Parse(strReply.Substring(0, 3)); } /// /// 建立进行数据连接的socket /// /// 数据连接socket private Socket CreateDataSocket() { SendCommand("PASV"); if (iReplyCode != 227) { throw new IOException(strReply.Substring(4)); } int index1 = strReply.IndexOf('('); int index2 = strReply.IndexOf(')'); string ipData = strReply.Substring(index1 + 1, index2 - index1 - 1); int[] parts = new int[6]; int len = ipData.Length; int partCount = 0; string buf = ""; for (int i = 0; i < len && partCount <= 6; i++) { char ch = Char.Parse(ipData.Substring(i, 1)); if (Char.IsDigit(ch)) buf += ch; else if (ch != ',') { throw new IOException("Malformed PASV strReply: " + strReply); } if (ch == ',' || i + 1 == len) { try { parts[partCount++] = Int32.Parse(buf); buf = ""; } catch (Exception) { throw new IOException("Malformed PASV strReply: " + strReply); } } } string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3]; int port = (parts[4] << 8) + parts[5]; Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ipAddress), port); try { s.Connect(ep); } catch (Exception) { throw new IOException("无法连接服务器"); } return s; } /// /// 关闭socket连接(用于登录以前) /// private void CloseSocketConnect() { if (socketControl != null) { socketControl.Close(); socketControl = null; } bConnected = false; } /// /// 读取Socket返回的所有字符串 /// /// 包含应答码的字符串行 private string ReadLine() { while (true) { int iBytes = socketControl.Receive(buffer, buffer.Length, 0); strMsg += GB2312.GetString(buffer, 0, iBytes); if (iBytes < buffer.Length) { break; } } char[] seperator = { '
' }; string[] mess = strMsg.Split(seperator); if (strMsg.Length > 2) { strMsg = mess[mess.Length - 2]; //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串, //但也会分配为空字符串给后面(也是最后一个)字符串数组, //所以最后一个mess是没用的空字符串 //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格 } else { strMsg = mess[0]; } if (!strMsg.Substring(3, 1).Equals(" "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串) { return ReadLine(); } return strMsg; } /// /// 发送命令并获取应答码和最后一行应答字符串 /// /// 命令 private void SendCommand(String strCommand) { Byte[] cmdBytes = GB2312.GetBytes((strCommand + "\r
").ToCharArray()); socketControl.Send(cmdBytes, cmdBytes.Length, 0); ReadReply(); } #endregion } }
5. FTP文件传输原理
在遇到了一个wireshark数据包分析题之后,看到了ftp的相关信息,但是没找到相关的flag信息,请教了大佬的解释,才知道ftp文件传输并不是在21端口,ftp文件传输有主动和被动两种方式,
被动(PASV)模式:
PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条控制连接。当需要传送数据时,服务器在命令链路上用PASV命令告诉客户端:“我打开了XXXX端口,你过来连接我”。于是客户端向服务器的XXXX端口发送连接请求,建立一条数据链路来传送数据。
服务器控制端口(21),服务器端等待的数据传输端口(动态申请)
ftp服务器动态申请一个端口(一般大于1024)然后告诉客户端,我在这个端口上等待你的连接,客户端收到以后便向服务器的这个端口发起连接,数据连接建立以后,数据传输就可以开始了
端口计算方法:172,16,101,104,7,254,256*7+254=2046
一次完整的被动连接及数据传输过程:
状态: 正在连接 172.16.101.104:21...
状态: 连接建立,等待欢迎消息...
响应: 220 Serv-U FTP Server v6.4 for WinSock ready...
命令: USER test
响应: 331 User name okay, need password.
命令: PASS ****
响应: 230 User logged in, proceed.
状态: 已连接
状态: 读取目录列表...
命令: PWD
响应: 257 "/" is current directory.
状态: 列出目录成功
状态: 正在连接 172.16.101.104:21...
状态: 连接建立,等待欢迎消息...
响应: 220 Serv-U FTP Server v6.4 for WinSock ready...
命令: USER test
响应: 331 User name okay, need password.
命令: PASS ****
响应: 230 User logged in, proceed.
状态: 已连接
状态: 开始上传 E:\Downloads\liugong\liugong\404.htm
命令: CWD /
响应: 250 Directory changed to /
命令: TYPE A
响应: 200 Type set to A.
命令: PASV
响应: 227 Entering Passive Mode (172,16,101,104,8,86)
命令: STOR 404.htm
响应: 150 Opening ASCII mode data connection for 404.htm.
响应: 226 Transfer complete.
状态: 文件传输成功,传输了 2,052 字节 (用时1 秒)
状态: 读取目录列表...
命令: TYPE I
响应: 200 Type set to I.
命令: PASV
响应: 227 Entering Passive Mode (172,16,101,104,8,88)
命令: MLSD
响应: 150 Opening BINARY mode data connection for MLSD.
响应: 226 Transfer complete.
状态: 列出目录成功
主动(PORT)模式:
PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条控制连接。当需要传送数据时,客户端在命令链路上用PORT命令告诉服务器:“我打开了XXXX端口,你过来连接我”。于是服务器从20端口向客户端的XXXX端口发送连接请求,建立一条数据链路来传送数据。
一次完整的主动连接及数据传输过程:
状态: 正在连接 172.16.101.104:21...
状态: 连接建立,等待欢迎消息...
响应: 220 Serv-U FTP Server v6.4 for WinSock ready...
命令: USER test
响应: 331 User name okay, need password.
命令: PASS ****
响应: 230 User logged in, proceed.
状态: 已连接
状态: 开始上传 E:\Downloads\liugong\liugong\404.htm
命令: CWD /
响应: 250 Directory changed to /
命令: TYPE A
响应: 200 Type set to A.
命令: PORT 172,16,101,104,8,76
响应: 200 PORT Command successful.
命令: STOR 404.htm
响应: 150 Opening ASCII mode data connection for 404.htm.
响应: 226 Transfer complete.
状态: 文件传输成功,传输了 2,052 字节 (用时1 秒)
状态: 读取目录列表...
命令: TYPE I
响应: 200 Type set to I.
命令: PORT 172,16,101,104,8,77
响应: 200 PORT Command successful.
命令: MLSD
响应: 150 Opening BINARY mode data connection for MLSD.
响应: 226 Transfer complete.
状态: 列出目录成功
再回来说这一题,看到
计算端口为 4*256+17=1041
端口过滤,追踪tcp流
6. ftp200瓦什么水平
优肆竖陆秀裂顷水平。
FTP。一般骑友的大概设置在100-200之间,200的就比较优秀了。
FTP(FunctionalThresholdPower临界功率),是衡量自行车运动表现最常参考的指标,是指全力且稳定的方式骑乘纤渣1个小时所得到的平均功率最大值。功率的国际标准单位是瓦特(W),职业自行车手的FTP一般都在400W以上,而业余自行车手通常落在250~350W之间。
7. FTP错误列表的常见的错误信息
-----------------------------------
120 Service ready in NNN minutes.
服务在NNN时间内可用
-----------------------------------
125 Data connection already open; transfer starting.
数据连接已经打开,开始传送数据.
-----------------------------------
150 File status okay; about to open data connection.
文件状态正确,正在打开数据连接.
-----------------------------------
200 Command okay.
命令执行正常结束.
-----------------------------------
202 Command not implemented, superfluous at this site.
命令未被执行,此站点不支持此命令.
-----------------------------------
211 System status, or system help reply.
系统状态或系统帮助信息回应.
-----------------------------------
212 Directory status.
目录状态信息.
-----------------------------------
213 File status. $XrkxmL=
文件状态信息.
-----------------------------------
214 Help message.On how to use the server or the meaning of a particular non-standard command. This reply is useful only to the human user.
帮助信息。关于如何使用本服务器或特殊的非标准命令。
-----------------------------------
215 NAME system type. Where NAME is an official system name from the list in the Assigned Numbers document.
NAME系统类型。
-----------------------------------
220 Service ready for new user.
新连接的用户的服务已就绪
-----------------------------------
221 Service closing control connection.
控制连接关闭
-----------------------------------
225 Data connection open; no transfer in progress.
数据连接已打开,没有进行中的数据传送
-----------------------------------
226 Closing data connection. Requested file action successful (for example, file transfer or file abort).
正在关闭数据连接。请求文件动作成功结束(例如,文件传送或终止)
-----------------------------------
227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
进入被动模式
-----------------------------------
230 User logged in, proceed. Logged out if appropriate.
用户已登入。 如果不需要可以登出。
-----------------------------------
250 Requested file action okay, completed.
被请求文件操作成功完成 63
-----------------------------------
257 PATHNAME created.
路径已建立
-----------------------------------
331 User name okay, need password.
用户名存在,需要输入密码
-----------------------------------
332 Need account for login.
需要登陆的账户
-----------------------------------
350 Requested file action pending further inFORMation U
对被请求文件的操作需要进一步更多的信息
-----------------------------------
421 Service not available, closing control connection.This may be a reply to any command if the service knows it must shut down.
服务不可用,控制连接关闭。这可能是对任何命令的回应,如果服务认为它必须关闭
-----------------------------------
425 Can't open data connection.
打开数据连接失败
-----------------------------------
426 Connection closed; transfer aborted.
连接关闭,传送中止。
-----------------------------------
450 Requested file action not taken.
对被请求文件的操作未被执行
-----------------------------------
451 Requested action aborted. Local error in processing.
请求的操作中止。处理中发生本地错误。
-----------------------------------
452 Requested action not taken. Insufficient storage space in system.File unavailable (e.g., file busy).
请求的操作没有被执行。系统存储空间不足。 文件不可用
-----------------------------------
500 Syntax error, command unrecognized. This may include errors such as command line too long.
语法错误,不可识别的命令。 这可能是命令行过长。
-----------------------------------
501 Syntax error in parameters or arguments.
参数错误导致的语法错误
-----------------------------------
502 Command not implemented.
命令未被执行
-----------------------------------
503 Bad sequence of commands.
命令的次序错误。
-----------------------------------
504 Command not implemented for that parameter.
由于参数错误,命令未被执行
-----------------------------------
530 Not logged in.
没有登录
-----------------------------------
532 Need account for storing files.
存储文件需要账户信息!
-----------------------------------
550 Requested action not taken. File unavailable (e.g., file not found, no access).
请求操作未被执行,文件不可用。
-----------------------------------
551 Requested action aborted. Page type unknown.
请求操作中止,页面类型未知
-----------------------------------
552 Requested file action aborted. Exceeded storage allocation (for current directory or dataset).
对请求文件的操作中止。 超出存储分配
-----------------------------------
553 Requested action not taken. File name not allowed
请求操作未被执行。 文件名不允许
-----------------------------------
8. 存款ftp和贷款ftp什么区别
1、适用范围不同。
存贷款FTP和资金类FTP,各行可能有细微的差异,但总体而言,存款类FTP的适用范围是存款、贷款以及类信贷;资金类FTP适用于同业存拆放/存借款、债券、票据(无论是否在贷款科目)。
2、成本不同。
同样数量的资金只转移到了负责部门,而且从3.5%上升到了4%。这也是很多银行分行与总行资产负债部矛盾的爆发点,因为一般来说明简,贷款部也是存款部。陵森
在分行看来,中间的50BP全部都是资产负债部赚来的,资产负债部只有少数人,大银行资产负债部40-50人,股份制20-30人。但实际上,人工成本可以忽略不计。这50 BP也包含很多成本,主要是流动性管理的成本。
下调存贷款FTP有效果:
能使发放贷款的考核利润提升10~20%。目前一年期贷款的FTP考核利润(贷款收益率-存贷款FTP价格)约为200~250bps,五年期贷款的FTP考核利润略低。下调存贷款FTP价格20-25bps能使发放贷款的考核利润提尺槐亩升10~20%。
9. 骑行ftp150什么水平
新手水平。通常世界级的自谈码绝行车都具有至少360~400W以上的ftp能力,骑行ftp150是新手水平,而226km最顶尖的职业选手ftp在340~360w之间,业余的自行车模前选手的ftp通含姿常是在250~320w附近。