2017-12-13 4 views
0

Auf unserem Telefonsystem verwenden wir Multicast für Paging. Gelegentlich wird jemand bei einem Unfall auf den Knopf drücken und wir müssen Wireshark aufmachen, um den Krimi zu finden. Also habe ich ein Powershell-Skript erstellt, um auf neue Multicast-Pakete zu warten und sie zu protokollieren. Funktioniert gut, aber ich kann nur an einen Port binden.Listen auf mehreren Multicast-Ports

Ich habe versucht mit Start-Job und Workflows, ohne Erfolg. Das könnte aber ganz bei mir sein. Also ... Ideen, wie man das auf mehreren Ports hören kann?

$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 

Antwort

1

Sie sollten Listener auf verschiedenen Ports als Jobs ausführen können. Sie sollten die Jobs jedoch nicht in dieselbe Datei schreiben lassen, da dies zu gleichzeitigen Schreibversuchen führen könnte. Ein besserer Ansatz wäre, die die Arbeitsplätze zu STDOUT schreiben und Launchers periodisch ausgegeben von den Arbeitsplätzen holen und schreibt sie in eine Datei:

$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 
} 

Mit gesagt, dass, wäre es nicht einfacher sein zu haben WinDump Trace diese Pakete und rotieren die Capture-Dateien?

+0

Ich hatte fast das gleiche Skript mit dem Start-Job versucht, aber es hat nie wirklich begonnen. Ich werde mich ein wenig an deine Eingabe anpassen und schauen, ob ich mehr Erfolg habe. Wie für WinDump - meine Ausgabe ist entworfen, um nur eine Zeile pro Multicast "Sitzung" zu schreiben, so dass es einfach ist, das letzte gesendete Telefon nachzuschlagen. WinDump würde alle Pakete ausgeben. – SaintFrag

+0

* WinDump würde alle Pakete ausgeben. * Nicht, wenn Sie nach bestimmten Paketen filtern. –

+0

Entschuldigung, um zu verdeutlichen: WinDump würde auf allen Paketen für einen bestimmten Multicast ablegen. Das bedeutet, dass ich für eine bestimmte Telefon-Seite Hunderte von Paketen haben könnte. Während ich mit meinem Skript eine Zeile in meinem Protokoll hätte. – SaintFrag

Verwandte Themen