PowerShell TCP服务器

9

我想请问你,如何处理多个连接线程。

我按照以下方式实现了TCP服务器:

$endpoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any, 8989)
$listener = New-Object System.Net.Sockets.TcpListener $endpoint
$listener.Start()

do {
    $client = $listener.AcceptTcpClient() # will block here until connection
    $stream = $client.GetStream();
    $reader = New-Object System.IO.StreamReader $stream
    do {
        $line = $reader.ReadLine()
        Write-Host $line -fore cyan
    } while ($line -and $line -ne ([char]4))

    $reader.Dispose()
    $stream.Dispose()
    $client.Dispose()
} while ($line -ne ([char]4))
$listener.Stop()

这段代码一次只能处理一个线程。 你能给我一些建议,如何在PowerShell中创建一个可以处理多个客户端的TCP服务器?


1
也许为每个连接的客户端生成一个运行空间 - Ansgar Wiechers
请优先考虑使用 PS Jobs - Ranadip Dutta
很遗憾,Windows 10没有预装netcat.exe或nc.exe(OSX有)。不过至少现在它自带curl.exe了。 - js2010
1个回答

7

处理多个客户端需要使用多个线程,为此您需要使用runspaces。下面是可工作的代码,它接受多个客户端并在单独的线程(runspace)中处理每个客户端。

$Global:Listener = [HashTable]::Synchronized(@{})
$Global:CnQueue = [System.Collections.Queue]::Synchronized((New-Object System.collections.queue))
$Global:space = [RunSpaceFactory]::CreateRunspace()
$space.Open()
$space.SessionStateProxy.setVariable("CnQueue", $CnQueue)
$space.SessionStateProxy.setVariable("Listener", $Listener)
$Global:newPowerShell = [PowerShell]::Create()
$newPowerShell.Runspace = $space
$Timer = New-Object Timers.Timer
$Timer.Enabled = $true
$Timer.Interval = 1000
Register-ObjectEvent -SourceIdentifier MonitorClientConnection -InputObject $Timer -EventName Elapsed -Action {
    While($CnQueue.count -ne 0) {
        $client = $CnQueue.Dequeue()
        $newRunspace = [RunSpaceFactory]::CreateRunspace()
        $newRunspace.Open()
        $newRunspace.SessionStateProxy.setVariable("client", $client)
        $newPowerShell = [PowerShell]::Create()
        $newPowerShell.Runspace = $newRunspace
        $process = {
            $stream = $client.GetStream();
            $reader = New-Object System.IO.StreamReader $stream
            [console]::WriteLine("Inside Processing")
            # You have client here so do whatever you want to do here.
            # This is a separate thread so if you write blocking code here, it will not impact any other part of the program
        }
        $jobHandle = $newPowerShell.AddScript($process).BeginInvoke()
        #jobHandle you need to save for future to cleanup
    }
}
$listener = {
    $Listener['listener'] = New-Object System.Net.Sockets.TcpListener("127.0.0.1", "1234")
    $Listener['listener'].Start()
    [console]::WriteLine("Listening on :1234")
    while ($true) {
        $c = $Listener['listener'].AcceptTcpClient()
        If($c -ne $Null) {
            [console]::WriteLine("{0} >> Accepted Client " -f (Get - Date).ToString())
            $CnQueue.Enqueue($c)
        }
        Else {
            [console]::WriteLine("Shutting down")
            Break
        }
    }
}
$Timer.Start()
$Global:handle = $newPowerShell.AddScript($listener).BeginInvoke()

如需更详细的示例,请前往此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接