2012-08-27 38 views
6

Tôi đang cố gắng viết kịch bản để kiểm tra và ứng dụng bằng PowerShell. Bài kiểm tra nên bao gồm việc gửi một chuỗi đến một máy chủ từ xa qua UDP, sau đó đọc phản hồi từ máy chủ đó và thực hiện điều gì đó với kết quả. Sự giúp đỡ duy nhất tôi cần là có giữa hai ('gửi chuỗi', rồi 'nhận được trả lời') bước của kịch bản:Gửi và nhận dữ liệu qua UDP trong PowerShell

  1. Gửi chuỗi "ABCDEFG" đến máy chủ 10.10.10.1 trên cổng UDP 5000
  2. Nhận phản hồi từ máy chủ 10.10.10.1

Tôi khá quen thuộc với PowerShell, nhưng đây là lần đầu tiên tôi phải đối phó với ổ cắm, vì vậy tôi ở vùng nước xa lạ, và dường như tôi không hiểu vài ví dụ tôi đã tìm thấy trên các bài đăng.

+0

Hi, Kiểm tra như sau: http://www.leeholmes.com/blog/2009/10/28/scripting-network-tcp-connections-in-powershell/ Nó đề cập đến TCP, nhưng thay vào đó chúng ta có thể thay đổi được UDP . – Arcass

+0

Cảm ơn bạn, đó là một khởi đầu tốt và nó dẫn tôi đến một số bài viết khác và tài liệu MSDN, sau đó mở ra một số câu hỏi khác ... Liệu tuyên bố này "$ RemoteIpEndPoint = [Net.EndPoint] (New-Object Net.IPEndPoint ($ ([Net.IPAddress] :: Any, 0))) "có nghĩa là máy chủ sẽ nghe trên 0.0.0.0 và trên tất cả các cổng UDP? – CRCerr0r

+0

OK, vì vậy tôi thấy [ở đây] (http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx) rằng 'Bất kỳ' có nghĩa là nó sẽ lắng nghe trên tất cả các địa chỉ cục bộ và [tại đây ] (http://msdn.microsoft.com/en-us/library/k17zbw22.aspx) '0' có nghĩa là nó sẽ lấy bất kỳ cổng nào có sẵn. Câu hỏi của tôi là - nếu tôi tạo một đối tượng khách hàng, hãy kết nối với máy chủ từ xa và gửi một chuỗi, như sau: $ UDPclient = new-object System.Net.Sockets.UdpClient; $ UDPclient.Kết nối ($ remoteHost, $ port); $ UDPclient.Send ($ sendBytes, $ sendBytes.Length); Hệ điều hành/.NET xử lý lưu lượng truy cập trả về tự động khi tôi thực hiện điều này (để được tiếp tục): – CRCerr0r

Trả lời

5

Một số thời gian trở lại, tôi đã viết một kịch bản PowerShell đơn giản để gửi một UDP Datagram. Xem: http://pshscripts.blogspot.co.uk/2008/12/send-udpdatagramps1.html sẽ giúp bạn có một nửa ở đó. Tôi không bao giờ làm một nửa còn lại và viết phía máy chủ của điều này mặc dù!

<# 
.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

Cảm ơn, tôi đã tìm thấy bài đăng đó khi tôi đang tìm kiếm (trước khi tôi đăng ở đây) và nó rất hữu ích, nhưng có vẻ như cuộc đấu tranh chính của tôi là với phần biên nhận của nó ... – CRCerr0r

0

Dưới đây là mã của tôi:

$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() 

Nó như sau:

  1. Tạo một UDPClient với một cổng tự động gán (0).
  2. Lấy địa chỉ IP cục bộ và cổng được gán tự động của UDPClient và in ra cho người dùng.
  3. Truy xuất địa chỉ IP và cổng của người khác từ người dùng.
  4. Chuyển đổi chuỗi "heyo" từ mã hóa ASCII thành mảng byte và gửi nó tới đồng đẳng. (I tin nó sẽ nằm ở đầu của người ngang cho đến khi nó được "nhận", thậm chí trong vài giây.)
  5. Tạo IPEndPoint nhận gói UDP từ bất kỳ địa chỉ IP nào và bất kỳ cổng nào (0).
  6. Nhận bất kỳ dữ liệu nào được gửi từ đồng đẳng dưới dạng mảng byte mới với IPEndPoint đó làm thông số tham chiếu (hiện lưu trữ nguồn gốc của gói nhận được).
  7. Chuyển đổi mảng byte đã nhận thành chuỗi được mã hóa ASCII và in ra.
  8. Đóng UDPClient. (Hãy chắc chắn để làm điều này;! Cách khác, các nguồn lực sẽ kéo dài (cho đến khi bạn khởi động lại PS))

Vẻ đẹp của kịch bản này là nó rất đơn giản và dễ hiểu và bạn có thể sử dụng nó cả với localhost/127.0.0.1 (trong hai cửa sổ PowerShell riêng biệt) hoặc với địa chỉ IP bên ngoài, nếu đó là địa chỉ IP cục bộ, bạn sẽ biết vì địa chỉ IP được in ra cho bạn bởi tập lệnh.

Lưu ý rằng có một SendAsync và một ReceiveAsync cho UDPClient, nhưng không có thời gian chờ cho chúng. Một số người đã nấu các giải pháp phức tạp cho việc này, nhưng bạn cũng có thể sử dụng các lệnh Start-Job của PowerShell và các lệnh *-Job khác và đặt một vòng nhận trong mã chạy riêng.

1

Ok vì vậy các bạn ở trên đã cho bạn những client-side, và đây là một server-side code đơn giản:

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

  • Bạn có thể thử nghiệm bằng cách sử dụng IP 127.0.0.1 cho máy của bạn tại t phía khách hàng, mở 2 cửa sổ của PowerShell (một cho phía máy khách và một cửa sổ phía máy chủ).

  • Trong hơn 1 gói, bạn có thể sử dụng đoạn mã sau:

$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])"
}

Các vấn đề liên quan