如何使用powershell连接到tcp套接字以发送和接收数据?

时间:2015-04-20 22:54:29

标签: .net sockets powershell tcp

我写了一个小的Powershell脚本。

它使用.Net System.IO.StreamReader和System.IO.StreamWriter从/向TCP套接字读取和写入数据。

我想用它连接到套接字telnet样式并发送/接收命令。

我试图从System.IO.StreamReader读取带有ReadLine()方法的行,但是来自服务器的数据可能没有及时到达(?)或IDK。我没有使用异步命令。请帮帮我!

这是我的剧本:

$FTPServer = "localhost"
$FTPPort = "21"

$tcpConnection = New-Object System.Net.Sockets.TcpClient($FTPServer, $FTPPort)
$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true

while ($tcpConnection.Connected)
{
    while ($tcpStream.DataAvailable)
    {
        $reader.ReadLine()
    }

    if ($tcpConnection.Connected)
    {
        Write-Host -NoNewline "prompt> "
        $command = Read-Host

        if ($command -eq "escape")
        {
            break
        }

        $writer.WriteLine($command) | Out-Null
    }
}

$reader.Close()
$writer.Close()
$tcpConnection.Close()

这是输出:

PS C:\Windows\System32\WindowsPowerShell\v1.0> test.ps1
220 Microsoft FTP Service
prompt> user username
331 Password required
prompt> pass password
230-Directory has 58,145,996,800 bytes of disk space available.
prompt> 
230 User logged in.
500 Command not understood.
prompt> help
214-The following commands are recognized (* ==>'s unimplemented).
    ABOR 
    ACCT 
    ADAT *
    ALLO 
    APPE 
    AUTH 
    CCC 
    CDUP 
    CWD 
    DELE 
    ENC *
    EPRT 
    EPSV 
    FEAT 
    HELP 
    HOST 
    LANG 
    LIST 
    MDTM 
    MIC *
    MKD 
    MODE 
    NLST 
    NOOP 
    OPTS 
    PASS 
    PASV 
    PBSZ 
    PORT 
    PROT 
    PWD 
    QUIT 
    REIN 
    REST 
    RETR 
    RMD 
    RNFR 
    RNTO 
    SITE 
prompt> escape

PS C:\Windows\System32\WindowsPowerShell\v1.0>

4 个答案:

答案 0 :(得分:5)

尝试使用缓冲区读取响应。代码如下所示:

$tcpConnection = New-Object System.Net.Sockets.TcpClient($FTPServer, $FTPPort)
$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true

$buffer = new-object System.Byte[] 1024
$encoding = new-object System.Text.AsciiEncoding 

while ($tcpConnection.Connected)
{
    while ($tcpStream.DataAvailable)
    {

        $rawresponse = $reader.Read($buffer, 0, 1024)
        $response = $encoding.GetString($buffer, 0, $rawresponse)   
    }

    if ($tcpConnection.Connected)
    {
        Write-Host -NoNewline "prompt> "
        $command = Read-Host

        if ($command -eq "escape")
        {
            break
        }

        $writer.WriteLine($command) | Out-Null
    }
    start-sleep -Milliseconds 500
}

$reader.Close()
$writer.Close()
$tcpConnection.Close()

答案 1 :(得分:0)

您的阅读行挂起的原因可能是因为您没有终止使用' \ n'发送的字符串。

客户代码:

[System.Net.Sockets.TcpClient] $tcpClient = [System.Net.Sockets.TcpClient]::new("localhost", "50001")

$tcpStream = $tcpClient.GetStream()
[System.IO.StreamReader] $reader = [System.IO.StreamReader]::new($tcpStream)
[System.IO.StreamWriter] $writer = [System.IO.StreamWriter]::new($tcpStream)

while ($tcpClient.Connected) {
    while ($tcpStream.DataAvailable) {
        $res = $reader.ReadLine()
        Write-Host $res
    }
}

服务器代码(nodejs)

const server = net.createServer(socket => {
    socket.write(
        "Testing !" +
            socket.remoteAddress +
            ":" +
            socket.remotePort +
            "\n"
    );
    socket.pipe(socket);
    console.log("Client connected!");
});
server.listen(50001, "localhost");

它只是摇摇晃晃。

答案 2 :(得分:0)

我发现NetworkStream DataAvailable属性本身是不够的,在进入第二个while循环之前需要一点微调。我已经对此进行了测试,当通过telnet连接到CISCO设备时,它就像一种魅力。

$field_name = isset($field_name) ? $field_name :'';$calendar_id =isset($calendar_id) ? $calendar_id : 0; if ( $field_name ):?>
<select data-calendar-id="<?php echo $calendar_id ?>" name="<?php echo esc_attr($field_name); ?>" > <?php else: ?> <?php endif ?>
<?php foreach ($variations as $variation_id => $variation_data): ?>
<?php $variation_title = get_the_title( $variation_data['variation_id'] );

?>
    <option value="<?php echo $variation_data['variation_id'] ?>" ><?php echo substr(preg_replace('/\D/', '',str_replace(' ', '-',$variation_title)),4) ?></option>

<?php endforeach ?>
</select>

答案 3 :(得分:0)

我尝试了所有解决方案。.克里斯的建议有所帮助,需要检查读者是否也有东西。现在一切正常。

$FTPServer = "localhost"
$FTPPort = "21"

$tcpConnection = New-Object System.Net.Sockets.TcpClient($FTPServer, $FTPPort)
$tcpStream = $tcpConnection.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true

while ($tcpConnection.Connected) {
    while ($tcpStream.DataAvailable -or $reader.Peek() -ne -1 ) {
        $reader.ReadLine()
    }

    if ($tcpConnection.Connected) {
        Write-Host -NoNewline "prompt> "
        $command = Read-Host

        if ($command -eq "escape") {
            break
        }

        $writer.WriteLine($command) | Out-Null
        Start-Sleep -Milliseconds 10
    }
}

$reader.Close()
$writer.Close()
$tcpConnection.Close()

这是输出:

220 Microsoft FTP Service
prompt> user username
331 Password required
prompt> pass password
230 User logged in.
prompt> help
214-The following commands are recognized (* ==>'s unimplemented).
    ABOR 
    ACCT 
    ADAT *
    ALLO 
    APPE 
    AUTH 
    CCC 
    CDUP 
    CWD 
    DELE 
    ENC *
    EPRT 
    EPSV 
    FEAT 
    HELP 
    HOST 
    LANG 
    LIST 
    MDTM 
    MIC *
    MKD 
    MODE 
    NLST 
    NOOP 
    OPTS 
    PASS 
    PASV 
    PBSZ 
    PORT 
    PROT 
    PWD 
    QUIT 
    REIN 
    REST 
    RETR 
    RMD 
    RNFR 
    RNTO 
    SITE 
    SIZE 
    SMNT 
    STAT 
    STOR 
    STOU 
    STRU 
    SYST 
    TYPE 
    USER 
    XCUP 
    XCWD 
    XMKD 
    XPWD 
    XRMD 
214 HELP command successful.
prompt> list
150 Opening ASCII mode data connection.
425 Cannot open data connection.
prompt> escape

PS C:\Users\gazsiazasz>