用WinINet Api 开发FTP客户端

本文提供了一个使用VB.NET和WinInet DLL实现的FTP客户端示例代码,演示了如何进行目录和文件的操作,包括创建、删除目录,上传、下载文件等功能。
 

Option Explicit

Public Const MAX_PATH = 260                            ' 是由MFC定义的不要更改

Public Const INTERNET_OPEN_TYPE_PRECONFIG = 0
Public Const INTERNET_OPEN_TYPE_DIRECT = 1
Public Const INTERNET_OPEN_TYPE_PROXY = 3

Public Const INTERNET_INVALID_PORT_NUMBER = 0

Public Const INTERNET_FLAG_PASSIVE = &H8000000          ' 被动模式
Public Const INTERNET_FLAG_PORT = &O0                   ' 主动模式

Public Const INTERNET_SERVICE_FTP = 1
Public Const INTERNET_SERVICE_GOPHER = 2
Public Const INTERNET_SERVICE_HTTP = 3

Public Const ERROR_NO_MORE_FILES = 18

Public Const FTP_TRANSFER_TYPE_ASCII = &H1
Public Const FTP_TRANSFER_TYPE_BINARY = &H1

Public Const INTERNET_FLAG_RELOAD = &H80000000
Public Const INTERNET_FLAG_KEEP_CONNECTION = &H400000
Public Const INTERNET_FLAG_MULTIPART = &H200000

Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
End Type

Type WIN32_FIND_DATA
        dwFileAttributes As Long
        ftCreationTime As FILETIME
        ftLastAccessTime As FILETIME
        ftLastWriteTime As FILETIME
        nFileSizeHigh As Long
        nFileSizeLow As Long
        dwReserved0 As Long
        dwReserved1 As Long
        cFileName As String * MAX_PATH
        cAlternate As String * 16                            ' 是由MFC定义的不要更改
End Type

' 连接和初始化
' **********************************************************************************************************
Public Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _
    (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _
    ByVal sProxyBypass As String, ByVal lFlags As Long) As Long

Public Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _
    (ByVal hInternetSession As Long, ByVal sServerName As String, ByVal nServerPort As Integer, _
    ByVal sUsername As String, ByVal sPassword As String, ByVal lService As Long, _
    ByVal lFlags As Long, ByVal lContext As Long) As Long

Public Declare Function InternetCloseHandle Lib "wininet.dll" _
    (ByVal hInet As Long) As Integer


' Ftp目录操作命令
' **********************************************************************************************************
Public Declare Function FtpGetCurrentDirectory Lib "wininet.dll" Alias "FtpGetCurrentDirectoryA" _
    (ByVal hFtpSession As Long, lpszCurrentDirectory As String, ByRef lpdwCurrentDirectory As Long) As Boolean

Public Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" _
    (ByVal hFtpSession As Long, ByVal lpszCurrentDirectory As String) As Boolean

Public Declare Function FtpCreateDirectory Lib "wininet.dll" Alias "FtpCreateDirectoryA" _
    (ByVal hFtpSession As Long, ByVal lpszDirectory As String) As Boolean
   
Public Declare Function FtpRemoveDirectory Lib "wininet.dll" Alias "FtpRemoveDirectoryA" _
    (ByVal hFtpSession As Long, ByVal lpszDirectory As String) As Boolean

' Ftp文件操作命令
' **********************************************************************************************************
' 查找文件或目录
Public Declare Function FtpFindFirstFile Lib "wininet.dll" Alias "FtpFindFirstFileA" _
    (ByVal hFtpSession As Long, ByVal lpszSearchFile As String, _
    lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Long, ByVal dwContent As Long) As Long
' 查找下一个文件或目录
Public Declare Function InternetFindNextFile Lib "wininet.dll" Alias "InternetFindNextFileA" _
    (ByVal hFind As Long, lpvFindData As WIN32_FIND_DATA) As Long
' 下载文件
Public Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" _
    (ByVal hFtpSession As Long, ByVal lpszRemoteFile As String, _
    ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, ByVal dwFlagsAndAttributes As Long, _
    ByVal dwFlags As Long, ByVal dwContext As Long) As Boolean
' 上传文件
Public Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _
    (ByVal hFtpSession As Long, ByVal lpszLocalFile As String, _
    ByVal lpszRemoteFile As String, _
    ByVal dwFlags As Long, ByVal dwContext As Long) As Boolean
' 删除文件
Public Declare Function FtpDeleteFile Lib "wininet.dll" _
    Alias "FtpDeleteFileA" (ByVal hFtpSession As Long, _
    ByVal lpszFileName As String) As Boolean
' 文件改名
Public Declare Function FtpRenameFile Lib "wininet.dll" _
    Alias "FtpRenameFileA" (ByVal hFtpSession As Long, _
    ByVal lpszExisting As String, ByVal lpszNew As String) As Boolean


Public Sub main()

    On Error GoTo Ftp_Err

    Dim bActiveSession As Boolean                       ' 用于标记当前是否有活动会话
    Dim hOpen As Long                                   ' 用于保存当前会话的句柄
    Dim hConnection As Long                             ' 用于保存活动连接的句柄
    Dim EnumItemNameBag As New Collection               ' 用于保存Ftp目录结构
    Dim EnumItemAttributeBag As New Collection

    ' 开始 FTP 会话。
    hOpen = InternetOpen("VB Wininet", INTERNET_OPEN_TYPE_DIRECT, vbNullString, vbNullString, 0)
    If hOpen = 0 Then
        ErrorOut Err.LastDllError, "InternetOpen"
        GoTo Exit_Sub
    End If
   
    ' 连接到 FTP 服务器。
    Dim strServer As String, strUser As String, strPassword As String
    Dim nFlag As Long
    strServer = "127.0.0.1"
    strUser = "test"
    strPassword = "test"
    nFlag = INTERNET_FLAG_PASSIVE
   
    hConnection = InternetConnect(hOpen, strServer, INTERNET_INVALID_PORT_NUMBER, _
        strUser, strPassword, INTERNET_SERVICE_FTP, nFlag, 0)
    If hConnection = 0 Then
        ErrorOut Err.LastDllError, "InternetConnect"
        GoTo Exit_Sub
    End If
    bActiveSession = True
   
    ' 更改为服务器上新的 FTP 目录。
    Dim strRemoteFolder As String
    Dim bRet As Boolean
    strRemoteFolder = "/"
    bRet = FtpSetCurrentDirectory(hConnection, strRemoteFolder)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpPutFile"
        GoTo Exit_Sub
    End If
   
    ' 检查目录是否存在
    Dim pData As WIN32_FIND_DATA
    Dim hFind As Long, nLastError As Long
    strRemoteFolder = "test"
    pData.cFileName = String(MAX_PATH, 0)
    hFind = FtpFindFirstFile(hConnection, strRemoteFolder, pData, 0, 0)     ' 查找第一个文件或目录
    If hFind = 0 Then
        ' 没有找到
        Err.Clear
       
        ' 创建目录
        bRet = FtpCreateDirectory(hConnection, strRemoteFolder)
        If bRet = False Then
            ErrorOut Err.LastDllError, "FtpPutFile"
            GoTo Exit_Sub
        End If
       
    Else
        ' 已经存在
    End If
   
    ' 改变目录
    strRemoteFolder = "test"                    ' 使用相对目录和绝对目录都可以
    bRet = FtpSetCurrentDirectory(hConnection, strRemoteFolder)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpPutFile"
        GoTo Exit_Sub
    End If
   
    strRemoteFolder = ".."                    ' 使用相对目录和绝对目录都可以
    bRet = FtpSetCurrentDirectory(hConnection, strRemoteFolder)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpPutFile"
        GoTo Exit_Sub
    End If
   
    ' 目录改名
    ' Dim strNewFolder As String
    ' strNewFolder = "TTT"
    ' bRet = FtpRenameFile(hConnection, strRemoteFolder, strNewFolder)
    ' If bRet = False Then
    '     ErrorOut Err.LastDllError, "FtpRenameFile"
    '     GoTo Exit_Sub
    ' End If
   
    ' 删除目录
    strRemoteFolder = "test"
    bRet = FtpRemoveDirectory(hConnection, strRemoteFolder)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpRemoveDirectory"
        GoTo Exit_Sub
    End If
   
    ' 获取 FTP 当前目录内容
    Dim strItem As String
    hFind = FtpFindFirstFile(hConnection, "", pData, 0, 0)     ' 查找第一个文件或目录
    nLastError = Err.LastDllError                                 ' 没有错误返回0
    If hFind = 0 Then
        If (nLastError = ERROR_NO_MORE_FILES) Then
            MsgBox "This directory is empty!"
        Else
            ErrorOut nLastError, "FtpFindFirstFile"
        End If
        GoTo Exit_Sub
    End If
    strItem = Left(pData.cFileName, InStr(1, pData.cFileName, String(1, 0)))
    EnumItemNameBag.Add strItem
   
    ' 查找 FTP 目录中的下一个文件。
    If hFind <> 0 Then bRet = True
    Do While bRet
        bRet = InternetFindNextFile(hFind, pData)
        If bRet Then
            strItem = Left(pData.cFileName, InStr(1, pData.cFileName, String(1, 0)))
            EnumItemNameBag.Add strItem
        End If
    Loop
   
    ' 上传文件
    Dim strFileLocal As String, strFileRemote As String, dwType As Long
    dwType = FTP_TRANSFER_TYPE_ASCII
    strFileLocal = "d:/ftpTest.rar"
    strFileRemote = "ftpTest.rar"
    bRet = FtpPutFile(hConnection, strFileLocal, strFileRemote, dwType, 0)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpPutFile"
        GoTo Exit_Sub
    End If
   
    ' 下载文件
    strFileLocal = "c:/ftpTest.rar"
    strFileRemote = "ftpTest.rar"
    bRet = FtpGetFile(hConnection, strFileRemote, strFileLocal, False, _
        INTERNET_FLAG_RELOAD, dwType, 0)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpGetFile"
        GoTo Exit_Sub
    End If
   
    ' 文件改名
    Dim strNewFile As String
    strNewFile = "TTT.rar"
    bRet = FtpRenameFile(hConnection, strFileRemote, strNewFile)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpRenameFile"
        GoTo Exit_Sub
    End If
   
    ' 删除文件
    bRet = FtpDeleteFile(hConnection, strNewFile)
    If bRet = False Then
        ErrorOut Err.LastDllError, "FtpRemoveDirectory"
        GoTo Exit_Sub
    End If
  
Exit_Sub:
    ' 结束 FTP 会话。
    If hConnection <> 0 Then InternetCloseHandle hConnection
    hConnection = 0
    bActiveSession = False
    Exit Sub
Ftp_Err:
    MsgBox Err.LastDllError, vbCritical, "Test Ftp Client by WinInet.dll"
    GoTo Exit_Sub
End Sub

Function ErrorOut(dError As Long, szCallFunction As String)
    Dim strErrInf As String
    Select Case dError
        Case 12014
            strErrInf = "用户名或密码错"
        Case 12007
            strErrInf = ""
        Case 12003
            strErrInf = "目录操作错误"
        Case 12110
            strErrInf = "文件不存在"
    End Select
   
    MsgBox "错误编号:" & Str(dError) & vbCrLf & vbCrLf & strErrInf & vbCrLf & vbCrLf & szCallFunction, vbCritical, "WinINet FTP Client"
    Err.Clear
   
End Function


内容概要:本文档是PCI-SIG发布的工程变更通知(ECN),定义了基于MCTP(管理组件传输协议)的PCI Express管理接口(PCIe-MI),旨在为PCIe设备提供标准化的带外管理能力。PCIe-MI支持通过多种传输方式(如SMBus/I2C、I3C、USB、PCIe VDM、MMBI等)进行设备管理操作,包括发现设备信息、监控链路状态以及配置参数等。该接口适用于带外管理(由BMC发起)和带内管理(由主机CPU系统软件发起),并详细规定了消息格式、命令集(如Get Information、Get/Set Parameters)、操作流程及错误处理机制,同时明确了硬件与软件的可选性及其影响。 适合人群:从事服务器、存储或高性能计算领域硬件设计、固件开发或系统管理的研发工程师,尤其是涉及BMC、PCIe设备管理与远程运维的技术人员。 使用场景及目标:① 实现对PCIe设备(如GPU、NVMe硬盘、网卡)的远程带外管理,在主机操作系统未运行时仍能获取设备信息与配置状态;② 统一不同厂商PCIe设备的管理接口,降低BMC软件适配复杂度;③ 支持灵活的连接子分区配置与链路监控,提升数据中心设备的可维护性与自动化水平。 阅读建议:此文档技术细节丰富,建议结合PCIe基础规范、MCTP系列规范及实际硬件架构图进行深入理解,重点关注命令交互流程与错误恢复机制,以便在产品设计中正确实现与兼容。
内容概要:本文针对传统三电平并网逆变器存在的谐波含量高、电网不平衡工况适应性差及动态响应慢等问题,提出一种融合双极性倍频脉宽调制(DPWMA)、正负序分离锁相与电网电压前馈的综合控制策略,应用于有源中点箝位(ANPC)三电平并网逆变器。研究首先分析ANPC拓扑在开关损耗均衡、中点电位稳定和输出波形质量方面的优势,构建其高性能并网的硬件基础。随后,通过引入DPWMA调制策略提升等效开关频率,有效抑制低次谐波,优化稳态电能质量;采用正负序分离技术实现电网不平衡工况下的精准锁相同步,保障并网电流对称性;结合电网电压前馈控制,提前补偿电网扰动,显著增强系统动态抗扰能力和响应速度。最终,通过Simulink搭建的仿真模型在稳态运行、电网不平衡及动态扰动等多种工况下进行验证,结果表明该复合控制策略能显著降低并网谐波、提升锁相精度与系统稳定性,为大功率、高电能质量的并网应用提供可靠的技术方案。; 适合人群:具备一定电力电子与自动控制理论基础,从事新能源发电、电力系统自动化、逆变器研发等相关领域的科研人员和工程技术人员。; 使用场景及目标:①研究和设计高性能的三电平并网逆变器控制系统;②解决电网电压不平衡、谐波畸变等复杂工况下的并网难题;③通过仿真手段验证先进调制与控制策略(如DPWMA、正负序分离、前馈控制)的实际效果与协同作用。; 阅读建议:此资源以Simulink仿真为核心,紧密结合理论分析与工程实践,建议读者在学习时,不仅要理解各控制模块(如DPWMA调制、正负序分离锁相环)的设计原理,还需动手搭建和调试仿真模型,通过对比传统控制与所提策略的波形、谐波含量和动态响应曲线,深刻体会复合控制策略的优势,从而实现从理论到实践的完整闭环。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值