监听多个组播端口
Listen on multiple multicast ports
在我们的 phone 系统上,我们使用多播进行寻呼。偶尔有人会不小心按下按钮,我们必须启动 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
您应该能够 运行 不同端口上的侦听器作为作业。但是,您不应该让作业写入同一个文件,因为这可能会导致并发写入尝试。更好的方法是让作业写入 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 跟踪这些数据包并轮换捕获文件不是更容易吗?
在我们的 phone 系统上,我们使用多播进行寻呼。偶尔有人会不小心按下按钮,我们必须启动 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
您应该能够 运行 不同端口上的侦听器作为作业。但是,您不应该让作业写入同一个文件,因为这可能会导致并发写入尝试。更好的方法是让作业写入 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 跟踪这些数据包并轮换捕获文件不是更容易吗?