收听多个组播端口

时间:2017-12-13 16:50:30

标签: powershell multicast

在我们的电话系统上,我们使用多播进行分页。偶尔有人会在事故中按下按钮,我们必须启动Wireshark来追踪whodunit。因此,我构建了一个Powershell脚本来侦听新的多播数据包并进行记录。效果很好,但我只能绑定到一个端口。

我已尝试使用Start-Job和工作流程,但没有成功。但这完全可以在我身上。那么......关于如何在多个端口上进行监听的想法?

$outfile = "c:\multicast log\multicast.txt"

function StartListener{
    Param(
        [Parameter(Mandatory)]
        $IPAddress,
        [Parameter(Mandatory)]
        $Port
    )

    $client = New-Object System.Net.Sockets.UDPClient
    $client.ExclusiveAddressUse = $false;
    #$localEp = [System.Net.IPEndPoint]::New([IPAddress]::Any, $Port);
    $localEp = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any, $port)
    $remEP = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any,0)

    $client.Client.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::ReuseAddress, $true);
    $client.ExclusiveAddressUse = $false;

    $client.Client.Bind($localEp);
    $multicastaddress = [IPAddress]::Parse($IpAddress);
    $client.JoinMulticastGroup($multicastaddress);

    Write-Host "Listening. This will never quit so you will need to force close it"

    $NewStream = $true
    $last_remEP = ""
    #initialize last_now to something that won't interfere
    $last_now = (Get-Date).AddYears(-1)
    while ($true) {
        $receivedbytes = $client.Receive([ref]$remEP);
        $now = Get-Date
        $cur_remEP = $($remEP.ToString())
        if ($last_remEP -eq $cur_remEP) {
            if ($now -gt ($last_now).AddSeconds(1)) {
                $NewStream = $true
            } else {
                $NewStream = $false
            }
        } else {
            $NewStream = $true
        }
        if ($NewStream) {
            $last_remEP = $cur_remEP
            if ((type $outfile).Count -ge 100) {
                (Get-Content $outfile | Select-Object -Skip 25) | Set-Content $outfile
            }
            Add-Content $outfile "$($now.ToString("yyyy-MM-dd hh:mm:ss tt")) - Received multicast from $cur_remEP"
        }
        $last_now = $now
    }
}

Clear-Content $outfile
$now = Get-Date -Format "yyyy-MM-dd hh:mm:ss tt"
Add-Content $outfile "$now - multicast logging started"

startlistener 224.0.1.75 50008
startlistener 224.0.1.75 50009

pause

1 个答案:

答案 0 :(得分:1)

您应该能够在不同的端口上运行侦听器作为作业。但是,您不应该将作业写入同一文件,因为这可能会导致并发写入尝试。更好的方法是让作业写入STDOUT并让你的启动器定期从作业中获取输出并将其写入文件:

$addr  = '224.0.1.75'
$ports = ...
$sb = {
    Param(
        [Parameter(Mandatory=$true)]
        [Net.IPAddress]$IPAddress,
        [Parameter(Mandatory=$true)]
        [int]$Port
    )

    $client = New-Object Net.Sockets.UDPClient
    ...
}

$jobs = foreach ($port in $ports) {
    Start-Job -Name "${addr}:${port}" -ScriptBlock $sb -ArgumentList $addr, $port
}

while ($true) {
    $jobs | ForEach-Object {
        $output = Receive-Job -Id $_.Id
        if ($output) {
            "{0}`t{1}" -f $_.Name, $output | Add-Content $outfile
        }
    }
    Start-Sleep -Milliseconds 500
}

有了这样说,让WinDump跟踪这些数据包并旋转捕获文件会更容易吗?