【问题标题】:Send and Receive data via UDP in PowerShell在 PowerShell 中通过 UDP 发送和接收数据
【发布时间】:2012-08-22 08:03:24
【问题描述】:

我正在尝试使用 PowerShell 编写脚本来测试和应用程序。测试应该包括通过 UDP 向远程服务器发送一个字符串,然后从该服务器读取响应并对结果进行处理。我需要的唯一帮助是脚本的中间两个(“发送字符串”,然后是“接收响应”)步骤:

  1. 在端口 UDP 5000 上向服务器 10.10.10.1 发送字符串“ABCDEFG”
  2. 从服务器 10.10.10.1 接收响应

我对 PowerShell 比较熟悉,但这是我第一次处理套接字,所以我在陌生的水域,我似乎无法理解我在帖子中找到的几个示例。

【问题讨论】:

  • 您好,请检查以下内容:leeholmes.com/blog/2009/10/28/… 它指的是 TCP,但应该可以修改为我们的 UDP。
  • 谢谢,这是一个好的开始,它让我找到了一些其他文章和 MSDN 文档,然后又引发了一些其他问题......这个声明是否“$RemoteIpEndPoint = [Net.EndPoint]( New-Object Net.IPEndPoint($([Net.IPAddress]::Any, 0)))" 表示服务器会监听0.0.0.0和所有UDP端口?
  • 好的,所以我看到here 'Any' 意味着它将侦听所有本地地址,here '0' 意味着它将获取任何可用端口。我的问题是 - 如果我创建一个客户端对象,连接到远程服务器并发送一个字符串,如下所示: $UDPclient = new-object System.Net.Sockets.UdpClient; $UDPclient.Connect($remoteHost, $port); $UDPclient.Send($sendBytes, $sendBytes.Length);当我执行此操作时,OS/.NET 是否会自动处理返回流量(待续):
  • $RemoteIpEndPoint = [Net.EndPoint](New-Object Net.IPEndPoint($([Net.IPAddress]::Any, 0))); $receiveBytes = $UDPclient.Receive([Ref]$RemoteIpEndPoint);有一些“幕后”的魔法?

标签: sockets powershell udp


【解决方案1】:

Thomas 刚刚给了你客户端,下面是一个简单的服务器端代码:

$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)
  • 您可以在客户端为您的机器使用 IP 127.0.0.1 进行测试,打开 2 个 powershell 窗口(一个用于客户端,另一个用于服务器端)。

  • 对于超过 1 个数据包,您可以使用以下代码:

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

【讨论】:

  • 为什么要在循环内打开和关闭UdpClient?不可以重复使用吗?
  • @Bowi (Yes) UDP 总是这样……这个 PS 代码基本上是镜像what's done in C#。通常你会创建一次对象,然后收到很多次,然后在完成或 d/c 时关闭。
  • @Andrew 你在说谜语。 :-D 你的意思是可以重复使用它还是它总是在一个循环中打开和关闭?什么是“d/c”??
  • @Bowi 看看我评论的第一个字。 D/c 表示断开连接。
【解决方案2】:

这是我的代码:

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

它执行以下操作:

  1. 使用自动分配的端口 (0) 创建 UDPClient。
  2. 获取本地 IP 地址和 UDPClient 自动分配的端口并将其打印给用户。
  3. 从用户那里检索对等方的 IP 地址和端口。
  4. 将字符串“heyo”从 ASCII 编码转换为字节数组并将其发送给对等方。 (我相信它会一直停留在对等端的一端,直到它被“接收”,即使是几秒钟。)
  5. 创建一个从任何 IP 地址和任何端口 (0) 获取 UDP 数据包的 IPEndPoint。
  6. 接收从对等方发送的任何数据作为新字节数组,并以该 IPEndPoint 作为参考参数(现在存储接收数据包的来源)。
  7. 将接收到的字节数组转换为 ASCII 编码的字符串并打印出来。
  8. 关闭 UDPClient。 (请务必这样做;否则,资源将持续存在(直到您重新启动 PS)!)

这个脚本的美妙之处在于它非常简单直接,您可以将它与localhost/127.0.0.1(在两个单独的 PowerShell 窗口中)或外部 IP 地址一起使用,如果它是本地 IP地址,你已经知道了,因为本地 IP 是由脚本为你打印出来的。

请注意,UDPClient 有一个 SendAsync 和一个 ReceiveAsync,但它们没有超时。有些人为此制定了复杂的解决方法,但您也可以只使用 PowerShell 的 Start-Job 和其他 *-Job 命令并在单独运行的代码中放置一个接收循环。

【讨论】:

  • 只是想说谢谢你发布这个,只是试了一下,效果很好。
【解决方案3】:

前段时间,我编写了一个简单的 PowerShell 脚本来发送 UDP 数据报。请参阅:http://pshscripts.blogspot.co.uk/2008/12/send-udpdatagramps1.html,它会让你走到一半。不过,我从来没有做过另一半并编写服务器端!

<#  
.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 - tfl@psp.co.uk 
    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 

【讨论】:

  • 谢谢,我在搜索时确实找到了那个帖子(在我在这里发帖之前),它很有帮助,但看起来我的主要困难在于它的收据部分......
猜你喜欢
  • 2017-02-23
  • 1970-01-01
  • 2017-09-27
  • 2012-10-03
  • 2012-05-20
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多