.net 如何使用powershell连接tcp socket发送和接收数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29759854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to connect to tcp socket with powershell to send and receive data?
提问by gazsiazasz
I have written a little Powershell script.
我写了一个小的 Powershell 脚本。
It uses .Net System.IO.StreamReader and System.IO.StreamWriter to read and write data from/to the TCP socket.
它使用 .Net System.IO.StreamReader 和 System.IO.StreamWriter 从/向 TCP 套接字读取和写入数据。
I would like to connect to a socket telnet style with it and send/receive commands.
我想用它连接到套接字 telnet 样式并发送/接收命令。
I am trying to read the lines with the ReadLine() method from the System.IO.StreamReader but the data from the server maybe does not arrive in time(?) or IDK. I am not using async commands. Please help me with that!
我正在尝试使用 System.IO.StreamReader 中的 ReadLine() 方法读取行,但来自服务器的数据可能没有及时到达(?)或 IDK。我没有使用异步命令。请帮我解决这个问题!
Here is my script:
这是我的脚本:
$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()
And here is the output:
这是输出:
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>
回答by Jan Chrbolka
Try using a buffer to read in response. The code would look like this:
尝试使用缓冲区读取响应。代码如下所示:
$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()
回答by Chris Horan
I found that the NetworkStream DataAvailable property wasn't enough on its own, and that it needed a little nudge before entering the second while loop. I've tested this and it works like a charm when connected to a CISCO device over telnet.
我发现 NetworkStream DataAvailable 属性本身是不够的,在进入第二个 while 循环之前需要稍微调整一下。我已经对此进行了测试,当通过 telnet 连接到 CISCO 设备时,它就像一个魅力。
$routerAddress = "192.168.10.126"
$port = "23"
$tcp = New-Object System.Net.Sockets.TcpClient($routerAddress,$Port)
$tcpstream = $tcp.GetStream()
$reader = New-Object System.IO.StreamReader($tcpStream)
$writer = New-Object System.IO.StreamWriter($tcpStream)
$writer.AutoFlush = $true
while ($tcp.Connected)
{
write-host ([char]$reader.Read()) -NoNewline
while(($reader.Peek() -ne -1) -or ($tcp.Available)){
write-host ([char]$reader.Read()) -NoNewline
}
if ($tcp.Connected)
{
Write-Host -NoNewline "_"
$command = Read-Host
if ($command -eq "escape")
{
break
}
$writer.WriteLine($command) | Out-Null
}
}
$reader.Close()
$writer.Close()
$tcp.Close()
回答by gazsiazasz
I have tried all the solutions.. Chris's suggestion helped, it is needed to check if there's something coming from the reader also. Now it is working fine.
我已经尝试了所有的解决方案.. 克里斯的建议有帮助,需要检查是否还有来自读者的东西。现在它工作正常。
$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()
And here is the output:
这是输出:
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>
回答by Evgeny Danilenko
The reason why your read line hangs is probably because you are not terminating the string that you send with '\n'.
您的读取行挂起的原因可能是因为您没有终止使用 '\n' 发送的字符串。
Client code:
客户端代码:
[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
}
}
Server code (nodejs)
服务器代码(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");
it just werks.
它只是起作用。

