Read TCP packets directly as hex - vb.net

I have this System.Net.Sockets.TcpClient. I can make a connection and write packets to it accurately. The problem is want to read the packets as it is (as caught by sniffers in the hex form like 0F 03 56 56 etc.)
I tried looking at examples of GetStream.write but I fail to read them in such way. I also tried using a streamreader then convert the packets to hex but the thing I connect to sends screwed up packets which can't be converted or simple not in string form.
I hope I'm clear enough.
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
' Read can return anything from 0 to numBytesToRead.
' This method blocks until at least one byte is read.
netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
' Returns the data received from the host to the console.
Dim returndata As String = Encoding.ASCII.GetString(bytes)

Found the solution! Here it is:
Dim Bytes() as Byte = New Byte(1024){}
Array.Resize(Bytes, TcpClient.Client.Receive(Bytes, SocketFlags.None))
For Each B As Byte In Bytes
Debug.Print("Byte in HEX Format: " & B.ToString("X2"))
Next

Related

Convert unicode byte arrary to a binary byte arrary

I have a byte() array full of Unicode data. I need to convert this byte array to binary data.
The original data was binary data, but data was saved as Unicode, and thus these data structures are now all 2 times as large as they need to be.
Can I convert from a byte array of one type to another byte array, or is looping required to skip every other byte?
Edit:
Comments asked for more info
The original byte array is Unicode UTF32 looks to be the format.
The output byte array needs to remove that extra encoding.
So, assuming this, then EndianUnicode as bytes to toss out the extra data works quite well
This seems to work:
b2 = System.Text.Encoding.BigEndianUnicode.GetBytes
(System.Text.Encoding.UTF32.GetString(b))
Of course it not clear as to why the resulting array is not EXACTLY 1/2 in size but the above does seem to work.
Edit2:
Ok, as noted, the question was not ONLY how to convert, but was btye arrary to btye array. Further more, the array was indeed Unicode, but the original binary byte array was based on the users local code page (English).
So the CORRECT conversion I required was this:
b2 = System.Text.Encoding.Default.GetBytes
(System.Text.Encoding.Unicode.GetString(b))
However, the above converts from a byte arrary to a string, and then back to a byte array. My question was STILL how to do this from byte arrary to byte array. Turns out you can do this, and this is how:
Dim b() As Byte
b = reader(0) ' the array is filled with Unicode (air code)
Dim b2() As Byte
' convert byte array - not have to convert to strings
Dim cFrom As System.Text.Encoding = System.Text.Encoding.Unicode
Dim cto As System.Text.Encoding = System.Text.Encoding.Default
b2 = System.Text.Encoding.Convert(cFrom, cto, b)
As noted, above is byte() array to byte() array as per my original question.
Note that "default" in above is of course the default code page (in my case a computer running English version of windows).

Convert Any Image to ASCII Text

This has been particularly difficult and annoying to research given the fondness of "ASCII ART". That is NOT what I am trying to do here. I need to replicate a process from an old software package that basically converts an image, any image, into ASCII text before sending it to a printer. Here is an example of what it spits out...
The first two lines are commands. The next 315 lines are pure ASCII (well they call it ASCII but its obviously hex, (80 chars ber line), followed by several more commands and setup before executing the print.
I've written all the software already, with exception to converting the image to ascii. Originally, and according to the documentation, the printer should accept raw binary data of several image types. Well, after fighting with that for the past day, I now realize why the manufacturer themselves don't go down that road.
So, my question is, how best to go about converting an image to ascii (hex) characters to send to the printer? My first guess would be to iterate through each character and convert it but that also seems like the slowest approach.
Public Shared Sub ConvertImageHex(filepath As String)
Dim f_convOutBytes() As Byte = File.ReadAllBytes(filepath)
Dim totalStreamLength As Int32 = f_convOutBytes.Length
Dim labelOutStream(totalStreamLength) As Byte
f_convOutBytes.CopyTo(labelOutStream, 0)
Dim HexValue As String = String.Empty
Dim labelPath As String = IO.Path.GetTempPath & "testasci.lbl"
If File.Exists(labelPath) Then
File.Delete(labelPath)
End If
Dim fs As FileStream = New FileStream(labelPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Dim s As StreamWriter = New StreamWriter(fs)
s.Close()
fs.Close()
fs = New FileStream(labelPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
s = New StreamWriter(fs)
Dim i As Int32 = 0
For Each c In f_convOutBytes
i += 1
If i > 38 Then
s.Write(vbCrLf)
i = 0
End If
HexValue = Convert.ToString(Convert.ToInt32(c), 16)
s.Write(HexValue)
Next
s.Close()
fs.Close()
If Not s Is Nothing Then s = Nothing
If Not fs Is Nothing Then fs = Nothing
End Sub
Quotes from the docs (Probably too much into the weeds at this point):
d = download data
type = the type of data that will follow, using standard file name extensions
ASC - Graphic in ASCII format
ASCII graphics
ASCII-Graphic format
The stucture is similar to the IMG format, but uses only ASCII characters, to enable a easy usage for
host devices or ERP systems.
Following rules are used:
• all data are hex bytes, i.e. 0-9 and a-f or A-F
• The printer waits for data until the defined picture size is received.
• Spaces and carriage returns can be added on different locations. It is required that a
carriage return is sent at the end of the picture data.
• The image data can be compressed with a simple algorithm which is black/white
optimized.
• The image data are transmitted from top to bottom, each time from left to right. A value
byte 80 stands left of 01.
• The first line describes the width and the height of a picture. Width and height are 16 bit
values each in the Big-Endian format.
• Also if the width is not devidable by 8, it is required that the missing pixel must be
transmitted.
Each line will be transmitted with following values:
• Optional repetition factor, caused by 00 00 FF xx, whereby xx describes the amount of
copies of the current line.
• Picture data - whereby different descriptions are optional possible:
a: Zerobytes are displayed through the amount of bytes.Valid input: 00 to FF.
b: Blackbytes (FF) can also be described through the amount of bytes, beginning
from 81 (81 means 1 time FF, - valid values are 81 to FF ).
c: A directly encoded number of bytes starts with 80 - followed by the amount of data, i.e.
80 03 123456. The amout of transmitted bytes can be between 01 and 7F.
d: A repeated pattern of arbitrary bytes can be initiated with a sequence 00 nn xx, which
means that xx bytes will be inserted nn times.
Example: 00 04 AA generates AAAAAAAA.

Error reading UInt16 from BinaryReader

Why does this work
Dim mem As New MemoryStream()
Dim bin As New BinaryWriter(mem)
bin.Write(CUShort(1000))
Dim read As New BinaryReader(New MemoryStream(mem.ToArray))
MsgBox(read.ReadInt16)
The message box give me 1000 which is right. Then I try to use this
Dim mem As New MemoryStream()
Dim bin As New BinaryWriter(mem)
bin.Write(CUShort(1000))
Dim s As String = ASCII.GetString(mem.ToArray)
Dim read As New BinaryReader(New MemoryStream(ASCII.GetBytes(s)))
MsgBox(read.ReadInt16)
It gives me 831 which is incorrect. Now I try it with Unicode encoding. It works. But I want to use ASCII. Why is this, and what am I doing wrong?
What you experience happens because of the way the .NET Runtime stores strings in memory, and because different encodings have a different set of characters.
A (U)Short is represented in memory by two bytes. When you call ASCII.GetString() the byte array is interpreted as coming from an ASCII string and is therefore converted into a UTF-16 string. This conversion is performed because UTF-16 is the encoding that all strings are stored as in memory by the .NET runtime.
Encoding.Unicode however is the same as UTF-16, so (at this point) no extra conversion is needed to store the string in memory. The byte array is just copied and marked as a string, thus you get the very same bytes and the same UShort.
This fiddle illustrates what I'm talking about: https://dotnetfiddle.net/p4EKn9

Serial port in VBA without MSComm

I need to read and write byte arrays using COM-port and VBA.
I found a nice solution here
But this solution works only for String type for input/output data. I need a byte array. I tried to write new functions but I don't know how to accurately read this data. Can you help me?
You can sending an array in this way:
Dim bWrite(1 To 3) As Byte
bWrite(1) = &HA1
bWrite(2) = &HB2
bWrite(3) = &HC3
Dim wr As Long
rc = WriteFile(h, bWrite(1), 3, wr, 0) 'wr indicates how many bytes went to the port.
Example from here: https://strokescribe.com/en/serial-port-vb-winapi.html

vb.net serial port character encoding

I'm working with VB.NET and I need to send and receive bytes of data over serial. This is all well and good until I need to send something like 173. I'm using a Subroutine to send a byte that takes an input as an integer and just converts it to a character to print it.
Private Sub PrintByte(ByVal input As Integer)
serialPort.Write(Chr(input))
End Sub
If i try
PrintByte(173)
Or really anything above 127 it sends 63. I thought that was a bit odd, so i looked up the ASCII table and it appears 63 corresponds to the ? character. So i think what is happening is VB.NET is trying to encode that number into a character that it does not recognize so it just prints a ?.
What encoding should I use, and how would I implement the encoding change?
The issue here is the SerialPort.Encoding property. Which defaults to Encoding.ASCII, an encoding that cannot handle a value over 127. You need to implement a method named PrintByte by actually sending a byte, not a character:
Private Sub PrintByte(ByVal value As Integer)
Dim bytes() As Byte = {CByte(value)}
serialPort.Write(bytes, 0, bytes.Length)
End Sub