0
点赞
收藏
分享

微信扫一扫

【Powershell】Powershell实现TCP通讯

为什么要在做这个?

PowerShell 进行 TCP 通信可以在许多场景中发挥作用,包括但不限于以下几个方面:

  1. 网络服务监控和管理:通过 PowerShell,你可以编写脚本来检查服务器上的网络服务是否可用,例如检查某个端口是否打开、某个服务是否正在运行等。这对于监控和管理网络服务的健康状态非常有用。
  2. 远程服务器管理:PowerShell 提供了与远程计算机进行通信的功能,包括通过 TCP 连接执行命令和脚本。这使得你可以远程管理服务器、执行远程命令、获取远程计算机的信息等。
  3. 自动化任务和脚本:通过 PowerShell 的 TCP 通信功能,你可以编写脚本来执行各种自动化任务,如与网络设备进行通信、与 Web 服务进行交互、与其他应用程序进行数据交换等。这对于自动化任务和脚本编写非常有帮助。
  4. 网络编程和测试:如果你对网络编程感兴趣,PowerShell 提供了一些功能来进行 TCP 通信,可以用于编写网络应用程序或进行网络测试。你可以使用 PowerShell 创建 TCP 客户端和服务器,发送和接收数据,模拟网络通信等。

方法1:使用.NET Framework提供的类库来实现TCP通信

在PowerShell中,可以使用.NET Framework提供的类库来实现TCP通信。下面是一个简单的示例,展示了如何在PowerShell中使用System.Net.Sockets命名空间中的类来建立TCP连接、发送和接收数据:

$tcpClientType = @"
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

public class TcpClientExample
{
    public void Run()
    {
        // 服务器IP和端口
        string serverIP = "127.0.0.1";
        int serverPort = 12345;

        // 创建TCP客户端
        TcpClient client = new TcpClient();

        try
        {
            // 连接服务器
            client.Connect(serverIP, serverPort);

            // 获取网络流
            NetworkStream stream = client.GetStream();

            // 发送数据
            string message = "Hello, server!";
            byte[] data = Encoding.ASCII.GetBytes(message);
            stream.Write(data, 0, data.Length);
            Console.WriteLine("Sent: " + message);

            // 接收数据
            data = new byte[1024];
            int bytesRead = stream.Read(data, 0, data.Length);
            string response = Encoding.ASCII.GetString(data, 0, bytesRead);
            Console.WriteLine("Received: " + response);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
        finally
        {
            // 关闭连接
            client.Close();
        }
    }
}
"@

# 编译类型定义为程序集
Add-Type -TypeDefinition $tcpClientType

# 创建对象并调用自定义方法
$tcpClient = New-Object -TypeName TcpClientExample
$tcpClient.Run()

在这个示例中,我们使用了Add-Type命令来将一段C#代码添加到PowerShell会话中。这段C#代码定义了一个名为TcpClientExample的类,其中包含一个Main方法。这个类的目的是建立TCP连接、发送数据并接收服务器的响应。

在PowerShell中,我们首先使用Add-Type命令来将C#代码添加到会话中。然后,我们使用New-Object命令创建了一个TcpClientExample对象,并将其存储在$tcpClient变量中。接下来,我们调用$tcpClient对象的Main方法。

Main方法中,我们首先指定要连接的服务器的IP地址和端口号。然后,我们创建了一个TcpClient对象,该对象用于建立与服务器的TCP连接。接着,我们获取与服务器的连接的网络流(NetworkStream),这样我们就可以通过流发送和接收数据。

在示例中,我们发送了一条消息("Hello, server!")到服务器。我们将消息转换为字节数组,并使用网络流的Write方法将数据发送给服务器。

然后,我们准备接收服务器的响应。我们创建一个字节数组来存储接收到的数据,并使用网络流的Read方法从服务器接收数据。我们将接收到的字节数组转换为字符串,并将其打印到控制台。

最后,我们使用TcpClient对象的Close方法关闭与服务器的连接。

但是这样实现对于运维同学来说还是显得复杂了些。

方法2:简化版使用.NET Framework提供的类库来实现TCP通信

原理与代码

要在 PowerShell 中实现 TCP 通信,你需要借助 .NET Framework 中的类库来完成。在 .NET Framework 中,有一些用于 TCP 通信的类,如 System.Net.Sockets.TcpClientSystem.Net.Sockets.TcpListener。你可以使用这些类来创建 TCP 客户端和服务器,并进行数据的发送和接收。

服务器端代码:

# TCP 服务器
# 创建侦听
$port = 12345
$listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Any, $port) # 创建TCP侦听
$listener.Start() # 启动侦听

$tcpClient = $listener.AcceptTcpClient()  # 等待 客户端建立连接后才会继续
$stream = $tcpClient.GetStream()

$buffer = New-Object byte[] 1024
$bytesRead = $stream.Read($buffer, 0, $buffer.Length) # 等待 客户端在stream中write数据后才会继续
$datafromclient = [System.Text.Encoding]::ASCII.GetString($buffer, 0, $bytesRead) #byte to string
Write-Host $datafromclient

$stream.Write([System.Text.Encoding]::ASCII.GetBytes("Hello, client!"), 0, 14) # 将要发送到Cliet的byte流写进stream

$stream.Close()
$tcpClient.Close()
$listener.Stop()

客户端代码

# TCP 客户端
# 建立连接
$serverip = "192.168.11.199"
$port = 12345
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($serverip, $port)

$stream = $tcpClient.GetStream()   # 获取流
$buffer = [System.Text.Encoding]::ASCII.GetBytes("Hello, server!") # 将要发送的数据转变为Byte
$stream.Write($buffer, 0, $buffer.Length) #将byte流写进stream

$buffer = New-Object byte[] 1024  # 创建buffer
$bytesRead = $stream.Read($buffer, 0, $buffer.Length) # 等待 当服务端将数据write到stream中之后才会继续;将stream中的byte读出来,读取长度是buffer的长度
$datafromserver = [System.Text.Encoding]::ASCII.GetString($buffer, 0, $bytesRead) # 将从stream中读取的的byte转换成string
Write-Host $datafromserver

$stream.Close() # 关闭stream
$tcpClient.Close() # 关闭连接

之前提供的示例与这个示例是相同的。这个示例展示了如何使用 .NET Framework 类库在 PowerShell 中实现基本的 TCP 通信。

这个示例中,我们创建了一个 TCP 服务器和一个 TCP 客户端。服务器监听本地 IP 地址的 12345 端口,并接受传入的连接。客户端连接到服务器的 IP 地址和端口。

服务器首先接受客户端的连接,并获取与客户端通信的网络流($stream)。然后,服务器从流中读取数据,并将读取到的数据发送回客户端。

客户端连接到服务器,并获取与服务器通信的网络流($stream)。然后,客户端将数据发送到服务器,并从流中读取服务器发送的响应数据。

这个示例是一个简化的演示,用于展示如何使用 .NET Framework 类库在 PowerShell 中实现 TCP 通信。

执行演示

首先确定服务器的IP及端口使用情况

【Powershell】Powershell实现TCP通讯_.NET Framework

在服务器端侦听端口,并确认端口已处与侦听状态

【Powershell】Powershell实现TCP通讯_通讯_02

在客户端验证下端口的连通性

【Powershell】Powershell实现TCP通讯_TCP_03

证明可以连通

【Powershell】Powershell实现TCP通讯_夏明亮_04

此时 在服务器上也可以看到客户但与服务器的端口连接已经处于ESTABLISHED状态了

【Powershell】Powershell实现TCP通讯_通讯_05

如果您看本文只是为了测试客户端和服务器端的端口连通情况,到这里就可以了。

在服务器端接收Client的数据

【Powershell】Powershell实现TCP通讯_Powershell_06

此时在客户端上与服务器建立TCP连接

【Powershell】Powershell实现TCP通讯_通讯_07

此时服务器的等待状态就会发生改变

【Powershell】Powershell实现TCP通讯_Powershell_08

顺便在服务器端检测下连接状况

【Powershell】Powershell实现TCP通讯_TCP_09

服务器端继续执行GetStream()并从stream中获取byte流

【Powershell】Powershell实现TCP通讯_Powershell_10

在客户端上执行GetStream()并向stream中写入byte流

【Powershell】Powershell实现TCP通讯_通讯_11

此时服务器端的状态就会自动发生变化,并获取到客户端发来的数据Hello Server!

【Powershell】Powershell实现TCP通讯_Powershell_12

我们在从服务器端向stream中写入数据

【Powershell】Powershell实现TCP通讯_Powershell_13

然后在客户端接收数据

【Powershell】Powershell实现TCP通讯_TCP_14

最后分别再服务器和客户端上关闭stream、client以及listener

【Powershell】Powershell实现TCP通讯_TCP_15


【Powershell】Powershell实现TCP通讯_夏明亮_16


补充:客户端和服务器端的发生和接收操作并不是死板的一发一收;而是双方都可以连续多次发送,而接收方则可以在发送方多次发送后一次性地从stream中取出数据。

我为什么些这篇文章呢?因为再最近的项目实施的过程中出现一个问题,服务器的端口明明是开放访问的且没有任何异常;但是同网段的其他服务器就是无法访问这个端口,其他端口有的正常有的不正常;那么肯定是怀疑环境中存在安全软件或装置进行了阻止,但是用户那边坚持说没有阻止访问;那我们就想到把我们的服务器程序先停止释放端口,然后使用powershell侦听这个端口,然后测试该端口是否可以访问;凭此来反证环境中存在未知的安全装置。

为什么不用现成的工具呢?一来好用的工具少,二来生产环境安全要求较高也担心小工具会有安全风险;既然powershell能轻松应对那肯定就是首选了。

举报

相关推荐

0 条评论