☰
Win7与TwinCAT间FTP通讯:从IIS搭建到文件上传下载实战
2026/9/29 4:45:27 网站建设 项目流程

简介:这是一份讲解两台 PC 间搭建 FTP 通讯的实操文档,适合工业自动化、网络运维及 TwinCAT 使用者参考。文档基于 Win7 平台,从创建 FTP 专用用户入手,依次介绍启用 Windows FTP 服务、通过 IIS 管理器添加 FTP 站点、设置内网 IP/端口与访问权限,并给出使用 TwinCAT FTP Client 上传和下载文件的具体样例,覆盖了 PC1 建服务端、PC2 连客户端的完整流程,可帮助读者快速建立可用的文件传输通道。资源为单个 docx 文档,压缩包仅 439KB,内容紧凑、步骤明确,无需额外依赖即可阅读;已有 192 人学习。文档以图文并茂方式呈现,按实操顺序拆解每一步,并特别标注启用 Web 管理工具、指定内网 IP、控制写入权限等关键注意事项,可有效减少初次配置时的踩坑时间。同时,文档还包含 TwinCAT 库引用与功能块调用的代码示例,便于在 PLC 项目中直接移植,对需要实现控制器与上位机之间数据交换的工程人员有较强参考价值。

1. 两台 PC 间实现 FTP 通讯:一条把 Win7 与 TwinCAT 绑在一起的文件通道

工控现场里“两台 PC 间实现 FTP 通讯”最常见的需求,不是搭一个互联网服务器,而是让一台装着 TwinCAT 的工控机把配方、报警记录或采集数据定时丢到另一台普通 Windows PC 上归档。这份资料的思路很直接:PC1 用 Win7 自带的 IIS 组件起一个 FTP Server,PC2 侧用带授权的 TwinCAT FTP Client 功能块去访问它。全程不需要装任何第三方 FTP 工具,也不涉及路由器或公网,难点集中在三处——Windows 功能勾选、IIS 站点参数、TwinCAT 功能块里 sNetID 和路径的约定。适合电气工程师、上位机开发和做数据归档的人照着做一遍。我先按实测顺序把服务器端搭起来,再拆上传和下载两套 TwinCAT 程序。

2. 在 Win7 上把 FTP 服务器立起来:本地用户、IIS 开关与站点参数

2.1 先建一个专用登录用户,别用 Administrator 顶着上

FTP 登录本质上是一次 Windows 账户认证。IIS 的 FTP 服务在 Win7 上默认不开放匿名访问给任意网络用户,你要不建一个本地用户,后面站点配置里只能选“匿名”,文件所有权和权限记录都会变得很怪。我更习惯在 PC1 上单独建一个账户,比如 TestUser / TestPwd123,让它在 FTP 根目录有读写权,其他目录一概不碰。

创建路径是“我的电脑 → 管理 → 本地用户和组 → 用户 → 右键新建用户”,输入用户名和密码后直接创建即可。注意两点:一是“用户下次登录时须更改密码”这个勾最好去掉,否则第一次登录就要改密码,TwinCAT 功能块里没法配合;二是如果网络环境是你自己控制的,密码复杂度策略可以关掉,避免出现 TestPwd123 这种明明能过却因为策略被拒的情况。

如果现场只有一台 PC 单机测试,而且你的 FTP 站点选择匿名访问,那这一步可以跳过,但我不建议。多一个可控的隔离变量,后面排障时更容易定位到底是账号问题还是网络问题。

2.2 Windows 功能开关:FTP 服务与 Web 管理工具要一起勾

搭建 IIS 的 FTP 服务要从“控制面板 → 程序 → 打开或关闭 Windows 功能”进去。这里有个比较容易翻车的地方:打开功能窗口后,必须勾选“Internet 信息服务”下的“FTP 服务”,同时把“Web 管理工具”整棵展开全部勾上。也可以在开始菜单直接搜“打开或”快速定位这个窗口,搜索结果第一条就是。

原因:IIS 管理器本身不在 FTP 服务组件里,而在 Web 管理工具组件里。只勾 FTP 服务,系统虽然装好了 FTP 引擎,但“管理工具”里不会出现“Internet 信息服务(IIS)管理器”,开始菜单也搜不到,后面就卡住了。两个都勾上,点确定后系统会花几分钟部署组件,期间不需要重启,但别把网卡禁用或者断网。

注意:只勾 FTP 服务不勾 Web 管理工具,控制面板里不会出现 IIS 管理器,这是这个场景下最容易卡住的地方。

2.3 IIS 管理器里添加站点:IP、端口、SSL 与权限怎么定

组件就绪后,从“控制面板 → 系统和安全 → 管理工具”打开 IIS 管理器。在左侧连接树里右键你的服务器节点,选择“添加 FTP 站点”。站点名称随便起,关键是物理路径——这就是 FTP 的根目录,建议单独建一个目录,别直接指向 C 盘根或系统盘。

绑定对话框里有几个参数值得逐一说:

参数推荐值说明
IP 地址当前内网 IP先 ipconfig 确认,选错会导致另一端连不上
端口21除非网络策略有要求,否则保持默认
自动启动 FTP 站点勾选避免服务器重启后站点不自动拉起
SSL无 或 允许内网传输选“无”最省事,过追溯要求选“允许”
身份验证匿名 或 基本建议建测试用户后用基本验证,便于权限隔离
授权规则读取 / 写入测试阶段只勾读取,确认链路通了再放开写入

身份验证页面里,匿名访问适合纯内部共享;如果前面建了 TestUser,这里就选“基本”,指定允许 TestUser 访问,然后按需勾“读取”和“写入”。我一般测试阶段只勾读取,确认链路通了再放开写入,减少一个变量。

这一段之后,FTP Server 端已经可用。可以顺手在 PC1 本机用浏览器输ftp://内网IP验证一下,能列出目录再进下一步。如果本机都访问不了,别急着查 TwinCAT,先把服务器自身问题解决掉。

3. 上传方向:用 FB_FTP_FileUploadEx 一次调用把文件推上服务器

3.1 库引用与授权前提:这功能块不是免费的

TwinCAT 侧要用到 TcFTPClient.lib。这组功能块的商业前提是必须有 TwinCAT FTP Client 授权,没有授权功能块会报错或者干脆无法激活。工程里通常还需要 TcSystem.lib、TcBase.lib 和 STANDARD.lib 一起引用,TcFTPClient 里面的数据类型和句柄定义依赖它们。

在 TwinCAT XAE 里操作:解决方案管理器 → 引用 → 右键添加库,输入 TcFTPClient 搜索。库加好后,写程序时智能提示里会出现 FB_FTP_FileUploadEx、FB_FTP_Open、FB_FTP_FileDownload、FB_FTP_Close 等。注意 TcFTPClient.lib 和 TcSystem.lib 的版本最好和你的 TwinCAT 版本同代,否则编译时会出现接口不匹配的提示。

授权怎么看:连接上真实 PLC 后,在 TwinCAT 的系统管理器中打开 Licensing 页面,找 FTP Client 相关条目。如果授权状态灯是红的,功能块调用后会一直卡在 busy 或者直接报错,排查起来相当迷惑,所以建议先确认授权再动手。

3.2 最简单的上传:FB_FTP_FileUploadEx 一锤子买卖

文档给的上传样例用的是 FB_FTP_FileUploadEx,这是一个封装好的功能块:输入参数配好,给一个上升沿,它内部完成连接、上传、关闭的全过程,省掉了 Open 和 Close 的显式调用。代码如下:

PROGRAM MAIN VAR FB_FTPFileUpload1 : FB_FTP_FileUploadEx; startstop : BOOL; busy : BOOL; err : BOOL; errid : UDINT; progress : UDINT; END_VAR
FB_FTPFileUpload1( sNetID := '', sHost := '172.16.235.100', nPort := DEFAULT_FTP_PORT, sUsername := 'TestUser', sPassword := 'TestPwd123', sSrcFile := '\Program Files\TestFile1.txt', sDesFile := '\TestFolder\File1.txt', bExecute := startstop, tTimeout := T#15s, bBusy => busy, bError => err, nErrId => errid, nProgress => progress );

逻辑说明:这是一个标准的带参功能块调用。bExecute 由 startstop 变量触发,功能块内部自行完成连接、传输和断开,输出端通过 bBusy、bError 反映实时状态。sSrcFile 指向 ADS 设备的本地文件,sDesFile 指向 FTP 服务器上的目标位置。

参数说明里最值得留意的是 sNetID 和路径约定。sNetID 是 ADS 网络 ID,功能块运行在本地时留空字符串即可;如果你把这段代码放在远程设备上或者走 ADS 路由,再填对应设备的 AMSNetId。sHost 填 FTP Server 的 IP,也就是 PC1 的内网 IP。nPort 用库里预定义的 DEFAULT_FTP_PORT,展开就是 21。sSrcFile 是 ADS 设备本地文件路径,这里用反斜杠;sDesFile 是 FTP Server 端的路径,但它是相对于 FTP 根目录的路径,不是绝对路径。上面的写法等价于把文件放到共享根目录下的 TestFolder 子目录里,文件夹不存在时功能块会自动新建。

提示:TwinCAT 功能块里的路径分隔符是反斜杠,和 Windows 一致;不要写成 C 语言风格的斜杠,否则功能块会当作无效路径。

3.3 上传完成怎么判断:别盯着 bExecute 看

功能块调用后,bBusy 为 TRUE 表示正在传输。等 bBusy 从 TRUE 变 FALSE,同时 bError = FALSE,就可以认为上传成功。很多新手会盯着 bExecute 判断,那是不对的,bExecute 只是触发,真正代表完成的是 busy/err 这对输出。

上传成功后,去 PC1 的共享根目录下确认 TestFolder 是否自动建出来、File1.txt 大小是否和源文件一致。如果 TestFolder 没建出来而 err 也没报,优先怀疑用户对根目录没有写权限,去 FTP 站点的授权规则里把 TestUser 的写权限勾上。我习惯在业务程序里加一个“传输完成后对比文件大小”的校验逻辑,虽然 TwinCAT 侧没有现成的文件大小对比块,但可以用 ADS 文件系统库去读本地文件长度,简单可靠。

4. 下载方向:Open / Download / Close 三段式状态机

4.1 为什么下载不提供一个封装块:句柄生命周期问题

下载没有像上传那种一锤子的 Ex 封装,文档给的是 FB_FTP_Open → FB_FTP_FileDownload → FB_FTP_Close 的结构。原因在于下载需要长时间占用连接,中间可能还要查目录、列文件,把连接句柄暴露出来更灵活。如果你在循环里反复调用下载功能块,每次开新连接开销很大,服务器端也会积累大量 TIME_WAIT 连接。

所以标准做法是用一个 CASE 状态机,把连接生命周期管起来。状态机的好处是每一步的执行结果都明确,Open 不成功就不进 Download,Download 不成功就停在当前状态等待排查,而不是让函数块内部把错误吞掉。

4.2 三段状态机的完整程序

变量声明:

PROGRAM MAIN VAR RisingEdge : R_TRIG; startstop : BOOL; state : BYTE; FB_FTP_Open1 : FB_FTP_Open; FB_FTP_FileDownload1 : FB_FTP_FileDownload; FB_FTP_Close1 : FB_FTP_Close; busy : BOOL; err : BOOL; errid : UDINT; handle : T_HFTP; progress : UDINT; END_VAR

PLC 程序:

RisingEdge(CLK := startstop); IF RisingEdge.Q THEN state := 1; END_IF CASE state OF 0: ; 1: FB_FTP_Open1( sNetID := '5.0.252.142.1.1', sHost := '172.16.9.223', nPort := 21, sUsername := 'TestUser', sPassword := 'TestPwd123', bExecute := TRUE, tTimeout := T#15s, bBusy => busy, bError => err, nErrId => errid, hFTP => handle ); IF NOT busy AND NOT err THEN FB_FTP_Open1(bExecute := FALSE); state := 2; END_IF 2: FB_FTP_FileDownload1( sNetID := '5.0.252.142.1.1', hFTP := handle, sSrcFile := '\TestFolder\File1.txt', sDesFile := '\Program Files\TestFile1.txt', bExecute := TRUE, tTimeout := T#15s, bBusy => busy, bError => err, nErrId => errid, nProgress => progress ); IF NOT busy AND NOT err THEN FB_FTP_FileDownload1(bExecute := FALSE); state := 3; END_IF 3: FB_FTP_Close1( sNetID := '5.0.252.142.1.1', hFTP := handle, bExecute := TRUE, tTimeout := T#15s, bBusy => busy, bError => err, nErrId => errid ); IF NOT busy AND NOT err THEN FB_FTP_Close1(bExecute := FALSE); state := 0; END_IF END_CASE

逻辑说明:状态 0 空闲;startstop 上升沿把 state 置 1;状态 1 打开连接,句柄存入 handle;状态 2 用这个句柄下载;状态 3 关闭连接,回到 0。每段都以 NOT busy AND NOT err 作为完成条件,并且完成后把对应功能块的 bExecute 拉低,这是状态机的常见习惯,防止功能块内部重复触发。

参数说明:sNetID 是 Client 端的 ADS 地址。文档注释写得很清楚:Client 端 sNetID,本机不填。如果你的程序直接跑在作为 FTP 客户端的工控机上,把 sNetID 留空即可;'5.0.252.142.1.1' 是远程访问场景下的 ADS 地址,填错会导致 Open 阶段直接报错。hFTP 句柄必须由 Open 功能块产生,并原封不动传给 Download 和 Close。

4.3 路径方向与句柄:最容易写反的两个点

下载时 sSrcFile 是服务器端路径(相对于 FTP 根目录),sDesFile 是客户端本地路径(针对 ADS 设备的文件系统)。这和上传正好相反,写反了就会出现“下载成功但本地找不到文件”或者“目标路径非法”。我见过不少同事把这两行直接复制粘贴,结果文件从服务器下载后被写进了一个根本不存在的目录。

另一个通用习惯是:把超时值 tTimeout 从 T#15s 放宽到 T#30s 或 T#60s。如果你传的是几十 MB 的文件,15 秒很可能不够,功能块会提前判超时,把原本正常的传输打断,这是最容易误判成网络问题的坑。

注意:下载时 sSrcFile 指向 FTP 服务器而不是客户端,路径约定和很多人的直觉相反。

5. 避坑清单:FTP 通讯现场最常翻车的五个配置点

5.1 上传 30MB 文件,Win7 服务器就掉线

现象:从 TwinCAT 客户端向 Win7 上的 FTP 服务器传大文件,传到一半连接中断,服务器侧文件不完整,再传又失败。小文件没这个问题,超过 30MB 就高概率出现。

原因:Win7 自带的 FTP 服务进程优先级设置偏高,传输时容易占满服务器所有带宽导致资源耗尽。IIS 在 Win7 上并非为高频大流量设计,它更适合轻量级文件交换。

解决:最直接的办法是控制单次传输文件大小在 30MB 以内,或者把 FTP Server 放到 Windows Server 版本系统上。如果一定要大文件,拆包分段上传,或者改用共享目录配合计划任务。

5.2 IIS 管理器怎么都搜不到

现象:勾选了 FTP 功能,控制面板管理工具里却没有“Internet 信息服务(IIS)管理器”,开始菜单搜索也搜不到。

原因:IIS 管理器属于“Web 管理工具”组件,和“FTP 服务”是两个独立项。只勾 FTP 服务不勾 Web 管理工具,等于只装了引擎没装控制台。

解决:重新进入“打开或关闭 Windows 功能”,把“Internet 信息服务 → Web 管理工具”整棵展开后全部勾上,确定后等待组件安装完毕。另外注意 Win7 家庭版本身没有 IIS 管理器,只有专业版及以上版本才有这个完整组件,装系统时就得注意版本选择。

5.3 TwinCAT 端连不上,Open 或 Upload 直接报错

现象:FB_FTP_Open 或 FB_FTP_FileUploadEx 的 bError 置 TRUE,errid 指向连接类错误码,检查 IP 和用户名密码都看不出问题。

原因:最常见的是三个原因叠加——防火墙拦了 21 端口;FTP 站点绑定 IP 与实际 IP 不一致;或者 sNetID 填错了,填了别的设备的 ADS 地址。

解决:先在 PC2 上用命令行验证:ftp 172.16.9.223,能提示输入用户名密码说明网络和端口通;不通就去 PC1 防火墙入站规则里放行 21 端口和 FTP 被动端口范围。Windows 防火墙对 FTP 有专门的内置规则,很多情况下只需允许“FTP 服务器”和“FTP 服务器-被动模式”通过即可。

5.4 路径到底是 Server 的还是 Client 的:写反了文件就没了

现象:上传时把 sSrcFile 填成客户端绝对路径,sDesFile 填成服务器绝对盘符路径,结果功能块报“路径无效”;下载时反过来,文件出现在错误位置。

原因:TcFTPClient 功能块对路径的约定和大多数人直觉相反——sDesFile 端从 FTP 根目录起算。比如服务器上真实目录是 D:\FTPRoot\TestFolder,功能块里写 \TestFolder\File1.txt 而不是 D:\FTPRoot\TestFolder\File1.txt。

解决:统一遵循约定:上传时 sSrcFile 是 ADS 本地文件,sDesFile 是 FTP 根目录后的相对路径;下载时反过来,sSrcFile 是 FTP 根目录后的相对路径,sDesFile 是 ADS 本地路径。如果不确定,先只测试一个 1KB 小文件,确认落点再批量跑。

5.5 触发器没加 R_TRIG,文件被重复传输

现象:一次上升沿操作,服务器上出现多个副本,或传输任务反复执行。

原因:bExecute 直接接手动按钮或常 ON 变量,功能块在每个周期都被重新触发。Ex 类功能块内部有状态机,但触发信号长期为 TRUE 时依然可能重复启动。

解决:把 startstop 先用 R_TRIG 做一次边沿检测,用 Q 输出作为 bExecute;或者自己维护一个“任务进行中”标志位,传输期间锁住后续触发。文档样例里直接接变量能跑,但正式项目里这是隐患,尤其是手自动切换或者上位机一直给 TRUE 信号时,问题会放大。

6. 验证一条 FTP 链路是否真的通:先从 cmd 走一遍,再让功能块上

不管服务器端配置得多仔细,TwinCAT 功能块参数背得多熟,我最后一步永远是先手工验证网络通路,再跑 PLC 程序。具体做法是在 PC2 上打开命令行,输入 ftp 加上 PC1 的 IP 地址,然后按顺序输入用户名和密码:

ftp 172.16.9.223 # 提示输入用户名:TestUser # 提示输入密码:TestPwd123 # 登录成功后依次执行: dir put testfile.txt

如果 dir 能列出目录、put 能成功上传,说明 21 端口、账号权限、防火墙全链路都通。接下来再回到 TwinCAT 工程里调试功能块,排错范围就只剩功能块参数本身了。这一步虽然简单,但能把问题范围砍掉一半:网络层面的错直接暴露在命令行里,而不是让功能块的 errid 帮你猜。

功能块验证顺序我一般固定为:先跑上传样例(FB_FTP_FileUploadEx),用 1KB 的小文件验证路径约定正确;再跑下载三段状态机,验证 handle 传递、Close 是否正常释放;最后才改成真实业务文件,逐步放大到几十 MB。

如果上传成功、下载也成功,但客户端本地找不到下载下来的文件,检查 sDesFile 里的路径是否存在——ADS 设备上的 \Program Files\ 目录往往需要管理员权限才能写入,换到 D:\Test\ 这类自定义目录通常会顺利得多。

另外提一个容易被忽略的事:TwinCAT FTP Client 授权。在没有授权或授权过期的机器上,功能块可能编译能过、运行时不报错,但文件就是不落盘;这种情况要去看 TwinCAT 系统管理器里授权的状态灯。资料里附带了一份 TcFTPClient.chm 帮助文档,里面每个功能块的参数说明比我上面列的更细,遇到 nErrId 报错先翻那个文件,比网上乱搜效率高。

从那以后,我每次搭这种链路都强制先走一遍 cmd 手工登录,再让功能块上,半小时就能确认通不通,省下大半天的排查时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询