【问题标题】:"A socket operation was attempted to an unreachable network" when downloading FTP file下载 FTP 文件时,“尝试对无法访问的网络进行套接字操作”
【发布时间】:2015-12-16 22:24:30
【问题描述】:

我是 PowerShell 和 FTP 脚本的新手,所以请善待。我已经搜索了很多,但找不到使用脚本从 FTP 服务器简单地下载文件的方法。我从cmd.exe 开始并尝试了ftp 子命令,但没有成功。所以我切换到 PowerShell (v4.0)。我看过各种下载 FTP 文件的示例,但没有一个对我有用。这是我最近的尝试:

$Username = "username"
$Password = "password"
$LocalFile = "C:\Users\myuser\MyFile.xlsx"
$RemoteFile = "ftp://ftp.example.com/MyFile.xlsx"

$req = [System.Net.FtpWebRequest]::Create($RemoteFile)
$req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
$req.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$req.UseBinary = $true
$req.UsePassive = $true
$req.KeepAlive = $false

# Everything works to this point.

try {
    # This throws exception.
    $resp = [System.Net.FtpWebResponse]$req.GetResponse()
}
catch {
    $msg = $_.Exception
    Write-Host "Exception: $msg" -ForegroundColor Red
}

# More code will go here later to write the data to the local file.

# Clean up.
if ($resp -ne $null) {
    $resp.Close()
    $resp = $null
}

我得到的错误是:

System.Management.Automation.MethodInvocationException: Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: 227 Entering Passive Mode (172,16,13,205,5,250).
." ---> System.Net.WebException: The remote server returned an error: 227 Entering Passive Mode (172,16,13,205,5,250).
. ---> System.Net.Sockets.SocketException: A socket operation was attempted to an unreachable network 172.16.13.205:1530
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Net.FtpControlStream.QueueOrCreateDataConection(PipelineEntry entry, ResponseDescription response, Boolean timeout, Stream& stream, Boolean& isSocketReady)
   at System.Net.FtpControlStream.PipelineCallback(PipelineEntry entry, ResponseDescription response, Boolean timeout, Stream& stream)
   at System.Net.CommandStream.PostReadCommandProcessing(Stream& stream)
   at System.Net.CommandStream.ContinueCommandPipeline()
   at System.Net.FtpWebRequest.TimedSubmitRequestHelper(Boolean async)
   at System.Net.FtpWebRequest.SubmitRequest(Boolean async)
   --- End of inner exception stack trace ---
   at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
   at System.Net.CommandStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
   at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
   at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
   at System.Net.FtpWebRequest.GetResponse()
   at CallSite.Target(Closure , CallSite , Object )
   --- End of inner exception stack trace ---
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

我知道该文件存在并且可用,因为当我将ftp://username:password@ftp.example.com/MyFile.xlsx 粘贴到浏览器中时,系统会提示我下载该文件,并且一切正常。

FTP 服务器在我们的网络中,但我想要一个也适用于我们网络之外的 FTP 服务器的解决方案。

我做错了什么?

【问题讨论】:

    标签: powershell ftp ftpwebrequest


    【解决方案1】:

    问题是服务器配置错误。

    尝试对无法访问的网络 172.16.13.205:1530 进行套接字操作

    服务器在227 响应PASV 命令时返回其本地网络IP 地址。

    您的客户端(FtpWebRequest)自然无法连接到该地址并失败。

    必须正确配置服务器,才能知道并在 227 响应中显示其外部 IP 地址。


    一些 FTP 客户端可以通过以下任一方式克服这种错误配置:

    • 227 响应中忽略不可路由的 IP 地址并使用控制连接地址进行数据传输或
    • 使用EPSV 命令而不是PASV(服务器只用端口号响应,让客户端隐式使用控制连接地址)

    FtpWebRequest 也不能这样做。

    Windows 命令行 FTP 客户端 ftp.exe 甚至不支持被动模式。它仅支持主动模式,由于无处不在的 NAT 和防火墙,如今这种模式几乎无法工作。

    有关此类问题的详细信息,请参阅FTP connection modes (active and passive) 上的我的 文章。


    如果无法修复服务器,则需要使用另一个 FTP 客户端。

    例如WinSCP FTP/SFTP client,使用它的scripting interface,你可以使用下面的批处理文件(.bat):

    winscp.com /log=winscp.log /command ^
        "open ftp://username:password@ftp.example.com" ^
        "get MyFile.xlsx C:\Users\myuser\MyFile.xlsx" ^
        "exit"
    

    WinSCP 在227 响应中忽略不可路由的 IP 地址,并使用控制连接地址进行数据传输。

    (我是 WinSCP 的作者)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 2013-01-15
      • 2021-05-14
      • 2011-07-07
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      相关资源
      最近更新 更多