SFTP协议

article/2025/8/30 1:23:28
SFTP协议

SCP协议本身打开SSH通道时指定的是scp命令,而是用SFTP时指定的sftp。以下是一些具体的介绍,详细内容需要参考对应的RFC文件。

下面是目前整理的使用的一份:

1) 协议中数据包格式

通过安全通道传输的所有包的格式如下:

     uint32           length

     byte             type

     uint32           request-id

     ... 具体类型域 ...

length:整个包的长度,不包括长度域本身。因此,例如一个不包含具体类型域的包的长度域是5个字节,那么将有9个字节发送到路线上。实际上包的最大尺寸由客户端决定(它发送的读写请求包最大尺寸,外加一些字节的包开销)。所有服务器应当支持至少34000字节的包(这里的包尺寸是指全长,包括上述头部)。也就是允许读写最多32768个字节。

 

type:包的类型码。

 

request-id:从客户端来的每一个请求包含一个请求ID域,从服务端返回的每个响应也包含和服务器应答的请求一样的请求ID。一个可能的是实现是客户提供给我们一个单调递增的序号(模除2^32)。然而没有特殊的要求请求ID域是唯一的。

     

SFTP协议中只有两个包,INIT和VERSION,不需要使用请求ID。

 

2) 协议中各种包具体格式和响应

包的类型type如下:

SSH_FXP_INIT                1

SSH_FXP_VERSION             2

SSH_FXP_OPEN                3

SSH_FXP_CLOSE               4

SSH_FXP_READ                5

SSH_FXP_WRITE               6

SSH_FXP_LSTAT               7

SSH_FXP_FSTAT               8

SSH_FXP_SETSTAT             9

SSH_FXP_FSETSTAT           10

SSH_FXP_OPENDIR            11

SSH_FXP_READDIR            12

SSH_FXP_REMOVE             13

SSH_FXP_MKDIR              14

SSH_FXP_RMDIR              15

SSH_FXP_REALPATH           16

SSH_FXP_STAT               17

SSH_FXP_RENAME             18

SSH_FXP_READLINK           19

SSH_FXP_LINK               21

SSH_FXP_BLOCK              22

SSH_FXP_UNBLOCK            23

 

SSH_FXP_STATUS            101

SSH_FXP_HANDLE            102

SSH_FXP_DATA              103

SSH_FXP_NAME              104

SSH_FXP_ATTRS             105

 

SSH_FXP_EXTENDED          200

SSH_FXP_EXTENDED_REPLY    201

 

客户端初始化包

type    SSH_FXP_INIT

uint32  version

 

对这个消息的响应是下面的服务器初始化版本包SSH_FXP_VERSION。

 

服务器初始化包

type    SSH_FXP_VERSION

uint32  version

 

打开文件包

byte     SSH_FXP_OPEN

uint32   request-id

string   filename [UTF-8]

uint32   desired-access

uint32   flags

ATTRS  attrs

 

对这个消息的响应将会是SSH_FXP_HANDLE(如果操作成功的话)或者SSH_FXP_STATUS(如果操作失败)

 

关闭句柄

byte     SSH_FXP_CLOSE

uint32   request-id

string   handle

 

handle是以前SSH_FXP_OPEN或SSH_FXP_OPENDIR返回的句柄。句柄变为无效后立即请求已发送。

对此请求的响应将是一个SSH_FXP_STATUS消息。请注意,在一些服务器平台上关闭操作可能会失败。例如,如果服务器操作系统缓存写入,在冲洗缓存写入时发生错误,关闭操作就可能失败。

注意不论SSH_FXP_STATUS的结果,句柄是无效的。没有办法为客户恢复关闭失败的句柄。客户端必须释放与句柄关联的所有资源,无论状态。服务器应采取的任何步骤,它可以恢复从关闭失败,以确保服务器上的处理相关联的所有资源正确释放。

 

读取文件

byte     SSH_FXP_READ

uint32   request-id

string   handle

uint64   offset

uint32   length

 

handle 是被SSH_FXP_OPEN返回打开的文件句柄。如果不是被SSH_FXP_OPEN返回的句柄,服务器必须返回SSH_FX_INVALID_HANDLE。

   offset是偏移量(以字节为单位)相对于读取文件开始的地方。此字段被忽略,如果SSH_FXF_TEXT_MODE指定在打开的时候。

   length 是读取的最大字节数。

      服务器不能响应比的“length”参数指定的更多的数据。但是,服务器的响应可能较少的数据,如果达到EOF,遇到一个错误,或内部缓冲区的服务器无法处理这么大的要求。

      如果服务器指定一个非零的max-read-size在它的supported2扩展中,并且length小于max-read-size,没有返回length个字节暗示EOF或者错误发生。

 

写入文件

byte     SSH_FXP_WRITE

uint32   request-id

string    handle

uint64    offset

string    data

 

   handle是一个打开文件句柄被SSH_FXP_OPEN返回的。如果handle不是一个SSH_FXP_OPEN返回的句柄,服务器必须返回SSH_FX_INVALID_HANDLE。

   offset是偏移量(以字节为单位),相对于文件的开头写必须开始。此字段被忽略,如果SSH_FXF_TEXT_MODE是在打开期间指定。如果超出文件末尾写的话,会扩展文件。它是合法的,写一个偏移量超出该文件的末尾扩展的语义是从文件末尾写字节值0x00指定的偏移,然后是数据。在大多数操作系统上,如写不分配磁盘空间,而是创建一个稀疏文件。

   data是要写入文件的数据。

   服务器响应一个写请求一个SSH_FXP_STATUS消息。

 

获取文件属性

很多时候,文件属性是SSH_FXP_READDIR自动返回的。然而,有些时候需要专门获得命名文件的属性。可以使用SSH_FXP_STAT,SSH_FXP_LSTAT和SSH_FXP_FSTAT请求。

   SSH_FXP_STAT和SSH_FXP_LSTAT不同,仅仅在于SSH_FXP_STAT遵循在服务器上的符号链接,然而SSH_FXP_LSTAT不遵循符号链接。两者的有一样的格式:

  byte     SSH_FXP_STAT or SSH_FXP_LSTAT

  uint32   request-id

  string   path [UTF-8]

  uint32   flags

 

   其中request-id是请求标识符,path指定状态被返回的文件系统对象。服务器用SSH_FXP_ATTRS或者SSH_FXP_STATUS返回请求。

   flag字段指定客户端有特别兴趣的属性标志。这是到服务器的提示。例如,在某些操作系统上获取ower、group和acl信息是昂贵的操作,服务器可能不获取它们除非客户端表达出特别的兴趣。

   客户端不能保证服务器提供所有它感兴趣的字段。

  

   SSH_FXP_FSTAT不同于其他在于它返回一个打开的文件(文件句柄标识)的状态信息。

   byte      SSH_FXP_FSTAT

   uint32    request-id

   string    handle

   uint32    flags

 

      handle是一个SSH_FXP_OPEN或者SSH_FXP_OPENDIR打开的文件句柄。

   服务器用SSH_FXP_ATTRS或者SSH_FXP_STATUS来响应这个请求。

 

设置文件属性

文件属性可以使用SSH_FXP_SETSTAT和SSH_FXP_FSETSTAT请求来修改。

byte      SSH_FXP_SETSTAT

uint32    request-id

string    path [UTF-8]

ATTRS     attrs

 

byte      SSH_FXP_FSETSTAT

uint32    request-id

string    handle

ATTRS     attrs

 

path是属性被修改的文件系统对象(例如,文件或者目录)。如果对象不存在,或者用户没有足够的访问权限去改写属性,请求会失败。

handle是SSH_FXP_OPEN或者SSH_FXP_OPENDIR打开的文件句柄。如果句柄没有被足够的访问权限打开去改写请求的熟悉,请求会失败。

attrs指定被应用的修改属性。更多细节参看File Attributes节。

服务器用SSH_FXP_STATUS消息响应。

因为某些系统可能使用分离的系统调用来设置各种属性,可能某些属性已经被修改了,仍然返回一个失败的响应。如果可能,服务器应该避免这种情况;然而,客户端必须清楚这种可能性。

 

打开目录

byte     SSH_FXP_OPENDIR

uint32   request-id

string   path [UTF-8]

 

path字段是列举的(没有任何尾随的斜线)的目录的路径名。更多信息参看“File Names”。

如果“路径”并不是指到一个目录,服务器必须返回SSH_FX_NOT_A_DIRECTORY。

此消息的响应,将要么SSH_FXP_HANDLE(如果操作成功)或SSH_FXP_STATUS(如果操作失败)。

 

读取目录

byte     SSH_FXP_READDIR

uint32   request-id

string   handle

 

handle是由SSH_FXP_OPENDIR返回的句柄。如果handle是一个SSH_FXP_OPEN返回普通的文件句柄,服务器必须返回SSH_FX_INVALID_HANDLE。

服务器用一个SSH_FXP_NAME或SSH_FXP_STATUS消息响应这个请求。在一段时间,可能会返回一个或多个名称。完整的状态信息返回每个名称,以加速典型的目录清单。

如果没有更多的名字可以读取,服务器必须响应一个SSH_FXP_STATUS消息,错误代码的SSH_FX_EOF

 

删除文件

byte      SSH_FXP_REMOVE

uint32    request-id

string    filename [UTF-8]

filename是要删除的文件名称。更多信息参考“File Names”。

如果filename是一个符号链接,链接被删除,指向的文件不会被删除。

这个请求不能被用于移除目录,在这种情况下,服务器必须返回SSH_FX_FILE_IS_A_DIRECTORY。

服务器将会用SSH_FXP_STATUS消息响应这个请求。

 

重命名文件

byte       SSH_FXP_RENAME

uint32     request-id

string     oldpath [UTF-8]

string     newpath [UTF-8]

uint32     flags

 

  其中“request-id”是请求标识符,“oldpath“是现有的文件或目录的名称,”newpath“是为新的文件或目录名称。

   'flags' 是 0 或者以下值的组合:

   SSH_FXF_RENAME_OVERWRITE  0x00000001

   SSH_FXF_RENAME_ATOMIC     0x00000002

   SSH_FXF_RENAME_NATIVE     0x00000004

   如果服务器不支持请求的操作模式,它必须返回SSH_FX_OP_UNSUPPORTED。

   如果flags不包括SSH_FXP_RENAME_OVERWRITE,newpath指定的名称已经存在一个文件,服务器必须响应SSH_FX_FILE_ALREADY_EXISTS。

   如果flags包括SSH_FXP_RENAME_ATOMIC,目标文件已存在,它是在一个原子的方式取代。例如,有没有在时间上观察到的瞬间,其中的名称并不是指无论是旧的或新的文件。 SSH_FXP_RENAME_ATOMIC意味着SSH_FXP_RENAME_OVERWRITE。

   服务器将用SSH_FXP_STATUS消息来回应这个请求。

 

创建目录

byte      SSH_FXP_MKDIR

uint32    request-id

string    path [UTF-8]

ATTRS  attrs

其中request-id是请求标识符,path指定被创建的目录,attrs指定了应该被应用到创建上的属性。

服务器将用SSH_FXP_STATUS消息来响应这个请求。如果指定的文件或者目录已经存在了,错误将被返回。

 

移除目录

byte     SSH_FXP_RMDIR

uint32   request-id

string   path [UTF-8]

 

其中request-id是请求标识符,path指定被移除的目录。

服务器用SSH_FXP_STATUS消息响应请求。

 

状态响应

SSH_FXP_STATUS响应数据部分的格式如下:

byte     SSH_FXP_STATUS

uint32   request-id

uint32   error/status code

string   error message (ISO-10646 UTF-8 [RFC-2279])

string   language tag (as defined in [RFC-1766])

error-specific data

 

request-id指示服务端响应的客户端请求。

error/status code是机器可读的状态代码指示请求的结果。值SSH_FX_OK指示成功,其他值指示失败。实现必须准备能收到意想不到的错误代码,他们理智地处理(如他们视为等同于SSH_FX_FAILURE)。

error message是人类可读的错误描述。

language tag指示错误使用的语言。

error-specific data可能是空的,可能包含附加的错误信息。

 

句柄响应

SSH_FXP_HANDLE响应的格式如下:

byte      SSH_FXP_HANDLE

uint32    request-id

string    handle

 

handle是一个任意的字符串,用于标识一个打开的文件或服务器上的目录。句柄对客户端是不透明的,不要试图以任何方式解释或修改它。句柄字符串的长度不能超过256个字节的数据。

 

数据响应

SSH_FXP_DATA响应的格式如下:

byte     SSH_FXP_DATA

uint32   request-id

string   data

bool     end-of-file [optional]

      

data是一个任意字节的字符串,其中包含请求的数据。数据字符串最多可能被要求在SSH_FXP_READ请求的字节数,但也可能较短。

end-of-file此字段是可选的,如果是存在和为真的,它表明,EOF的是读期间到达的。这可以帮助客户避免了往返,以确定短读是否正常(由于EOF)或一些其他问题(例如有限的服务器的缓冲区。)

名称响应

SSH_FXP_NAME响应的格式如下:

byte     SSH_FXP_NAME

uint32   request-id

uint32   count

repeats  count times:

    string       filename [UTF-8]

    ATTRS        attrs

bool     end-of-list [optional]

 

count在这个响应中返回的名称的数目,filename和attrs重复count次。

filename是被返回的文件名。

attrs是该文件的属性。

end-of-list如果这个字段是存在的和为真,没有更多的读取条目了。除非请求是SSH_FXP_READDIR,否则字段应该被省略或为真。

 

属性响应

SSH_FXP_ATTRS响应的格式如下:

byte      SSH_FXP_ATTRS

uint32    request-id

ATTRS     attrs

 

attrs返回的文件属性。

 

1) 协议工作流程

客户端向服务器端上发送文件

 

客户端从服务器端上获取文件

 

 


http://chatgpt.dhexx.cn/article/PSLCx2WQ.shtml

相关文章

关于标志信息ZF、OF、SF、CF的理解

带标志加法器结构 零标志ZF 零标志是根据每一位加法器的计算结果 F i F_i Fi​相或得到的,所以只有在结果的每一位都为0的时候所有位相或才能得到0的输出,但是或门上有取反符号,所以在ZF标志的输出为1时代表结果全零,反之不全为0…

CF、SF、OF、ZF标志位

没学汇编,这种题我真是做一道错一道:-( OF(overflow flag) 溢出标志位 溢出标志位 OF 1 表示带符号整数运算时结果发生溢出。对于无符号整数运算,OF没有意义。 对于有符号数的溢出判断方式有: 1)采用一位符号位:思想…

cgo如何调用c++库

将c代码打包成静态库,再通过cgo调用,一直链接不上。起初以为是cgo只能用gcc,而我的静态库是是用g编译的,其实不然。 cgo调用c库,只需要在cpp源代码 include 头文件的时候,加上 extern "C" 就行了…

golang cgo 使用总结

文章目录 参数传递 基本数值类型切片字符串其他类型总结参考资料 CGO 提供了 golang 和 C 语言相互调用的机制。某些第三方库可能只有 C/C 的实现,完全用纯 golang 的实现可能工程浩大,这时候 CGO 就派上用场了。可以通 CGO 在 golang 在调用 C 的接口…

CGO总结

概述 cgo作为一个强大的工具,可以让go轻松实现调用c语言的巨额遗产。。。 问题 实际开发中,发现使用go语言调用c的动态库时,经常出现传入c的字符串发生变化的现象,如下: 情况1 由a.txt变为a.txt$\n 情况2 由plai…

cgo 机制 - 从 c 调用 go

文|朱德江(GitHub ID:doujiang24) MOSN 项目核心开发者 蚂蚁集团技术专家 专注于云原生网关研发的相关工作 本文 4656 字 阅读 12 分钟 一、前言 去年刚学 go 语言的时候,写了这篇 cgo 实现机制[1] ,介绍了 cgo 的基本…

深入学习CGO

深入学习CGO 快速入门基础知识import "C" 语句#cgo语句 GO与C的类型转换CGO函数调用CGO内部机制CGO内存模型C类封装成C APICGO调用在go runtime 层面的处理CGO的静态/动态库封装以及编译链接参数CGO定位内存泄露CGO性能CGO最佳使用场景总结参考文献: 很多…

快速上手 CGO,掌握在 Go 里写 C!

大家好,最近因为各种奇怪的原因,接触到了 Go 特色之一 CGO。这方面的相关内容也相对少一些,给大家抛砖引玉,有经验的大佬欢迎补充。 图片来源于 marlin 毕竟很多跨语言调用,还是会依赖 CGO 这个特性。希望大家在真正要…

DevOps学习心得总结

流程步骤: 1、PLAN 制定计划 (牢记交付给用户的目标) 2、CODE 开始编码 (使用相同的代码,不同版本的代码存储到仓库中,借助Git等工具在需要时合并【版本控制】) 3、BUILD 构建阶段…

DevOps工具链

DevOps是敏捷研发中持续构建(Continuous Build,CB)、持续集成(Continuous Integration,CI)、持续交付(Continuous Delivery,CD)的自然延伸,从研发周期向右扩展…

DevOps及DevOps常用的工具介绍

目录 1. 什么是 DevOps2. DevOps 概念的起源2.1. 单体架构 瀑布模式2.2. 分布式架构 敏捷开发模式2.2.1. 多人协同开发问题2.2.2. 多机器问题2.2.3. 开发和运维角色的天生对立问题 2.3. 微服务架构 DevOps 3. DevOps 到底是什么4. DevOps 常用的工具4.1. Jenkins4.2. Kubern…

DevOps 简史

【注】本文节译自:https://www.bmc.com/blogs/devops-history/   IT 行业的当前状态受技术进步在整个历史中所产生的连锁效应所影响。不时出现的新技术极大地改变了世界运转的方式。最近,技术进步似乎开始以惊人的速度出现。自从互联网出现以来&#…

DevOps 学习

目录 一、概述 1、CI/CD简介 二、Git简介 三、Jenkins简介 一、概述 DevOps是Development和Operations的组合,也就是开发和运维的简写。 DevOps集文化理念、实践与工具于一身,可以提高组织高速交付应用程序和服务的能力,与使用传统软件…

DevOps实践

数字化时代,技术的交付速度和质量,直接关系业务的发展和创新。IT 技术交付和运行的效率,成为决定数字化转型成败的关键,而 DevOps 要解决的问题正在于此,DevOps 成为数字化转型的重要一环。 能力构建 随着云原生技术的…

DevOps的前世今生

导语 DevOps诞生已经13年了,你理解他吗? 为什么相伴了13年,你仍然对他不甚了了呢? 你真的以为DevOps是一个筐,什么东西都可以往里装吗? 你以为DevOps落地就是找一个JIRA(敏捷管理工具&#…

Learning DevOps

什么是 DevOps DevOps(Development & Operations)/de’vps/ 是一组过程、方法与系统的统称,用于促进开发 (Dev)、技术运营 (Ops)和质量保障(QA)部门之间的沟通、协作与整合。 DevOps 的开发流程 软件从零开始到…

DevOps思想

什么是DevOps? DevOps是一种思想或方法论,它涵盖了开发、测试、运维的整个过程!DevOps强调开发、测试、运维、质检(QA)部门之间的有效沟通与协作。强调通过自动化的方法管理软件变更、软件集成。使软件从构建到测试、发布更加快捷、可靠&…

DevOps的发展史

公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! — 1 — 可操作的概述 多亏了云计算和开源,软件开发的速度从几年缩短到几个月。每家公司都在向一个软件公司转变。DevOps 已迅速成为公司大规模开发和部署软件的最有效方…

DevOps——简析

节选自百度等资料 知乎解析连接 一、DevOps的目的 只有一个:提高开发到运维发布版本的效率。 1.初级应用:开发运维一体化 2.最高阶的应用:端到端的概念。 DevOps 的三大支柱之中,即人(People)、流程&…

DevOps推广实践总结

中大型团队在敏捷DevOps转型过程中常见的实践总结 目录 1、聘用外部DevOps顾问 2、建立DevOps共识 3、采用“DevOps改进”而非“DevOps转型” 4、构建“比学赶超”的组织氛围 5、规范化DevOps实践 1、聘用外部DevOps顾问 小型团队可以不用聘用昂贵的外部教练,因…