每次连接尝试的 powershell TCPclient 超时

powershell TCPclient timeout per connection try

我正在尝试在 powershell 中为套接字创建超时,但我遇到了一个问题,即使经过许多小时的 Google 搜索,我也不知道如何解决。

$tcp = New-Object System.Net.Sockets.TcpClient
$tcp.Connect('127.0.0.0',"port1")

$tcp.Connect('127.0.0.0',"port2")

$tcp.Connect('127.0.0.0',"port3")

当服务器端监听系列中的第一个端口时,客户端通常会在一两秒后收到请求。但是,如果服务器端侦听系列中的第三个端口 - 客户端将花费 20 秒的时间尝试连接第一个端口,然后再花费 20 秒的时间尝试连接到第二个端口,然后当它尝试连接到服务器侦听的第三个端口 - 它直接连接。

正如我在 post 开头提到的,我在 Google 上搜索了很长时间以寻找答案,我自己也尝试了很多次。非常感谢您的帮助。

如何更改每次 TCP 连接尝试的等待时间?

这里是一个如何实现 .ConnectAsync(..) Method from the TcpClient Class 的示例,它允许测试 async 多个 TCP 端口和特定的 TimeOut 定义为参数。

注意,此功能需要.NET Framework 4.5+ if 运行 Windows PowerShell / .NET 核心 1.0+ 如果 运行 PowerShell 核心。

using namespace System.Diagnostics
using namespace System.Collections.Generic
using namespace System.Collections.Specialized
using namespace System.Net.Sockets
using namespace System.Threading.Tasks

function Test-TCPConnectionAsync {
    [cmdletbinding()]
    param(
        [parameter(Mandatory, Valuefrompipeline)]
        [string[]] $Target,

        [parameter(Mandatory, Position = 1)]
        [ValidateRange(1, 65535)]
        [int[]] $Port,

        # 1 second minimum, reasonable for TCP connection
        [parameter(Position = 2)]
        [ValidateRange(1000, [int]::MaxValue)]
        [int] $TimeOut = 1200
    )

    begin {
        $timer = [Stopwatch]::StartNew()
        $tasks = [List[OrderedDictionary]]::new()
    }
    process {
        foreach($t in $Target) {
            foreach($i in $Port) {
                $tcp = [TCPClient]::new()
                $tasks.Add([ordered]@{
                    Instance = $tcp
                    Task     = $tcp.ConnectAsync($t, $i)
                    Output   = [ordered]@{
                        Source       = $env:COMPUTERNAME
                        Destionation = $t
                        Port         = $i
                    }
                })
            }
        }
    }
    end {
        do {
            $id = [Task]::WaitAny($tasks.Task, 200)
            if($id -eq -1) {
                continue
            }
            $instance, $task, $output = $tasks[$id][$tasks[$id].PSBase.Keys]
            $output['Success'] = $task.Status -eq [TaskStatus]::RanToCompletion
            $instance.ForEach('Dispose') # Avoid any throws here
            $tasks.RemoveAt($id)
            [pscustomobject] $output
        } while($tasks -and $timer.ElapsedMilliseconds -le $timeout)

        foreach($t in $tasks) {
            $instance, $task, $output = $t[$t.PSBase.Keys]
            $output['Success'] = $task.Status -eq [TaskStatus]::RanToCompletion
            $instance.ForEach('Dispose') # Avoid any throws here
            [pscustomobject] $output
        }
    }
}

$ports = 80, 443, 8080, 389, 636
'google.com', 'cisco.com', 'amazon.com' | Test-TCPConnectionAsync $ports

如果你想对多台主机实现并行扫描,你可以找到一个使用Runspaces on my GitHub的例子。