I was trying to make a little TCP Client Send and Receive script to send actual date to an industrial camera. The device expects [date]<CR>
as end char, and sends back OK<CR>
or ER<CR>
message.
I've found a base script for send here: https://riptutorial.com/powershell/example/18118/tcp-sender
I've added StreamReader function to it, test with Hercules SETUP Utility and it gives back a return message... if the end char is <LF>
... But I need <CR>
to send and receive also. Communication manual, page 527.
Function Send-TCPMessage {
Param (
[Parameter(Mandatory=$true, Position=0)]
[ValidateNotNullOrEmpty()]
[string]
$EndPoint
,
[Parameter(Mandatory=$true, Position=1)]
[int]
$Port
,
[Parameter(Mandatory=$true, Position=2)]
[string]
$Message
)
Process {
# Setup connection
$IP = [System.Net.Dns]::GetHostAddresses($EndPoint)
$Address = [System.Net.IPAddress]::Parse($IP)
$Socket = New-Object System.Net.Sockets.TCPClient($Address,$Port)
# Setup stream wrtier
$Stream = $Socket.GetStream()
$Writer = New-Object System.IO.StreamWriter($Stream)
$Reader = New-Object System.IO.StreamReader($Stream)
# Write message to stream
$Message | % {
$Writer.WriteLine($_)
$Writer.Flush()
}
$Response = $Reader.ReadLine()
# Close connection and stream
$Stream.Close()
$Socket.Close()
return $Response
}
}
$retunMessage = Send-TCPMessage -Port 23 -Endpoint 127.0.0.1 -message "My first TCP message !"
Write-Host "Return Message = " $retunMessage
I was trying to test with Hercules SETUP Utility, and Google up the right parameter/setting for modify end character. With no success. Someone could help to identify, what parameters should I set to modify the end char to <CR>
?
For writing with System.IO.StreamWriter
, set its .NewLine
property (before writing to the stream):
$Writer.NewLine = "`r" # CR
For reading with System.IO.StreamReader
, you'll have to resort to character-by-character reading:
# Read a line terminated by a single CR
$lineBuf = [System.Text.StringBuilder]::new(80)
while (($codePoint = $Reader.Read()) -ne -1 -and $codePoint -ne 13) {
$null = $lineBuf.Append([char] $codePoint)
}
$Response = $lineBuf.ToString()
Note:
Normally, no extra effort is needed if your lines are terminated with CR only, because a line is defined as (from the System.IO.StreamReader
reader's .ReadLine()
docs; emphasis added):
a sequence of characters followed by a carriage return (0x000d), a line feed (0x000a), a carriage return followed by a line feed, Environment.NewLine, or the end-of-stream marker.
With file input, use of .ReadLine()
is sufficient. However, when communicating with devices / intermittent streams, the implication is that .ReadLine()
doesn't return until either EOF is reached or at least one additional character after a CR can be read, because it has to examine that additional character for being a LF, given that a CRLF sequence is a newline too.