2012-08-27 20 views
6

Próbuję napisać skrypt do testowania i aplikacji przy użyciu PowerShell. Test powinien polegać na wysłaniu łańcucha na zdalny serwer przez UDP, a następnie odczytaniu odpowiedzi z tego serwera i zrobieniu czegoś z wynikiem. Jedyna pomoc muszę to z dwóch środkowych („wysłać ciąg”, a następnie „otrzymać odpowiedź”) etapów skryptu:Wysyłanie i odbieranie danych przez UDP w PowerShell

  1. Wysłać string „ABCDEFG” do serwera 10.10.10.1 na port UDP 5000
  2. Odpowiedź zwrotną z serwera 10.10.10.1

Jestem dość zaznajomiony z PowerShell, ale to jest mój pierwszy kontakt z gniazdami, więc jestem w nieznanych wodach i nie mogę mieć sensu kilka przykładów, które znalazłem w postach.

+0

Cześć, Sprawdź: http://www.leeholmes.com/blog/2009/10/28/scripting-network-tcp-connections-in-powershell/ Odnosi się do TCP, ale powinno być możliwe do zmodyfikowania do nas UDP . – Arcass

+0

Dziękuję, to był dobry początek i to doprowadziło mnie do kilku innych artykułów i dokumentacji MSDN, które następnie otworzyły kilka innych pytań ... Czy ta deklaracja "$ RemoteIpEndPoint = [Net.EndPoint] (New-Object Net.IPEndPoint ($ ([Net.IPAddress] :: Any, 0))) "oznacza, że ​​serwer będzie nasłuchiwał na 0.0.0.0 i na wszystkich portach UDP? – CRCerr0r

+0

OK, więc widzę [tutaj] (http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx), że "Any" oznacza, że ​​będzie nasłuchiwał na wszystkich lokalnych adresach i [tutaj ] (http://msdn.microsoft.com/en-us/library/k17zbw22.aspx), że "0" oznacza, że ​​pobierze dowolny dostępny port. Moje pytanie brzmi: jeśli utworzę obiekt klienta, połącz się ze zdalnym serwerem i wyślij ciąg znaków: $ UDPclient = new-object System.Net.Sockets.UdpClient; $ UDPclient.Połącz ($ remoteHost, $ port); $ UDPclient.Send ($ sendBytes, $ sendBytes.Length); czy OS/.NET obsługuje ruch zwrotny automatycznie, kiedy to robię (należy kontynuować): – CRCerr0r

Odpowiedz

5

Jakiś czas temu napisałem prosty skrypt PowerShell, aby wysłać Datagram UDP. Zobacz: http://pshscripts.blogspot.co.uk/2008/12/send-udpdatagramps1.html, który zabierze Cię w połowie drogi. Nigdy nie robiłem drugiej połowy i piszę to po stronie serwera!

<# 
.SYNOPSIS 
    Sends a UDP datagram to a port 
.DESCRIPTION 
    This script used system.net.socckets to send a UDP 
    datagram to a particular port. Being UDP, there's 
    no way to determine if the UDP datagram actually 
    was received. 
    for this sample, a port was chosen (20000). 
.NOTES 
    File Name : Send-UDPDatagram 
    Author  : Thomas Lee - [email protected] 
    Requires : PowerShell V2 CTP3 
.LINK 
    http://www.pshscripts.blogspot.com 
.EXAMPLE 
#> 

### 
# Start of Script 
## 

# Define port and target IP address 
# Random here! 
[int] $Port = 20000 
$IP = "10.10.1.100" 
$Address = [system.net.IPAddress]::Parse($IP) 

# Create IP Endpoint 
$End = New-Object System.Net.IPEndPoint $address, $port 

# Create Socket 
$Saddrf = [System.Net.Sockets.AddressFamily]::InterNetwork 
$Stype = [System.Net.Sockets.SocketType]::Dgram 
$Ptype = [System.Net.Sockets.ProtocolType]::UDP 
$Sock  = New-Object System.Net.Sockets.Socket $saddrf, $stype, $ptype 
$Sock.TTL = 26 

# Connect to socket 
$sock.Connect($end) 

# Create encoded buffer 
$Enc  = [System.Text.Encoding]::ASCII 
$Message = "Jerry Garcia Rocks`n"*10 
$Buffer = $Enc.GetBytes($Message) 

# Send the buffer 
$Sent = $Sock.Send($Buffer) 
"{0} characters sent to: {1} " -f $Sent,$IP 
"Message is:" 
$Message 
# End of Script 
+0

Dzięki, znalazłem ten post, gdy szukałem (zanim napisałem tutaj) i było to pomocne, ale wygląda na to, że moja główna walka dotyczy części pokwitowania ... – CRCerr0r

0

Oto mój kod:

$client = new-object net.sockets.udpclient(0) 

write-host "You are $(((ipconfig) -match 'IPv').split(':')[1].trim()):$($client.client.localendpoint.port)" 

$peerIP = read-host "Peer IP address" 
$peerPort = read-host "Peer port" 

$send = [text.encoding]::ascii.getbytes("heyo") 
[void] $client.send($send, $send.length, $peerIP, $peerPort) 

$ipep = new-object net.ipendpoint([net.ipaddress]::any, 0) 
$receive = $client.receive([ref]$ipep) 

echo ([text.encoding]::ascii.getstring($receive)) 

$client.close() 

wykonuje następujące:

  1. Tworzy UDPClient z automatycznie przypisanego portu (0).
  2. Pobiera lokalny adres IP i automatycznie przypisany port UDPClienta i drukuje je użytkownikowi.
  3. Pobiera adres IP i port peer od użytkownika.
  4. Konwertuje ciąg "heyo" z ASCII-encoding na tablicę bajtów i wysyła ją do peera. (I wierzę, że będzie siedział tam po stronie równorzędnej, dopóki nie zostanie "odebrany", nawet przez pewną liczbę sekund.)
  5. Tworzy IPEndPoint, który pobiera pakiet UDP z dowolnego adresu IP i dowolnego portu (0).
  6. Odbiera wszelkie dane, które zostały wysłane od węzła sieci jako nową tablicę bajtów z tym parametrem IPEndPoint jako parametrem referencyjnym (który przechowuje teraz pochodzenie odebranego pakietu).
  7. Konwertuje odebraną tablicę bajtów na ciąg znaków zakodowany w kodzie ASCII i drukuje go.
  8. Zamyka UDPClient. (Upewnij się, aby to zrobić!; Inaczej, zasoby będą się utrzymywać (dopiero po ponownym uruchomieniu PS))

Piękno tego scenariusza jest to, że jest to bardzo proste i jednoznaczne i można go używać zarówno z localhost/127.0.0.1 (w dwóch oddzielnych oknach PowerShell) lub z zewnętrznym adresem IP, który, jeśli jest to lokalny adres IP, będzie już znany, ponieważ lokalny adres IP jest wydrukowany dla ciebie przez skrypt.

Należy zauważyć, że istnieje funkcja SendAsync i ReceiveAsync dla UDPClient, ale nie ma dla nich limitu czasu. Niektóre osoby opracowały skomplikowane obejścia tego problemu, ale można także po prostu użyć poleceń PowerShell Start-Job i innych poleceń *-Job i umieścić pętlę odbiorczą w osobnym kodzie.

1

Ok więc przyjaciel powyżej dał ci po stronie klienta, a tutaj jest prosty kod po stronie serwera:

$port = 2020
$endpoint = new-object System.Net.IPEndPoint ([IPAddress]::Any,$port)
$udpclient = new-Object System.Net.Sockets.UdpClient $port
$content = $udpclient.Receive([ref]$endpoint)
[Text.Encoding]::ASCII.GetString($content)

  • Możesz przetestować używając adresu IP 127.0.0.1 dla twojego komputera w t po stronie klienta, otwierając 2 okna powłoki powershell (po stronie klienta i po stronie serwera).

  • na więcej niż 1 pakietu można użyć poniższy kod:

$port = 2020
$endpoint = New-Object System.Net.IPEndPoint ([IPAddress]::Any, $port)
Try {
        while($true) {
                $socket = New-Object System.Net.Sockets.UdpClient $port
                $content = $socket.Receive([ref]$endpoint)
                $socket.Close()
                [Text.Encoding]::ASCII.GetString($content)
        }
} Catch {
        "$($Error[0])"
}

Powiązane problemy