I have written a little Powershell script.
It uses .Net System.IO.StreamReader and System.IO.StreamWriter to read and write data from/to the TCP socket.
I would like to connect to a socket telnet style with it and send/receive commands.
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!
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>
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()
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.
$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()
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With