Sometimes I need to work on applications that involve dealing with sockets, TCP, serial communications or other somewhat low-level stuff. For sockets, the .NET Framework offers the nice NetworkStream class which makes it much easier to read and write to a socket, particularly if you build StreamReaders and StreamWriters on top of it.
However, sometimes problems will arise with encoding, translations and so forth that can be a pain in the neck to debug, particularly on a live production system. Sometimes, one can resort to a tool such as a network protocol analyzer (like the NetMon tool included with Windows Server OSs), but not usually on a production server (at least around here, they are usually banned by the security groups in companies, and heavily restricted).
Still, sometimes you need to know exactly what your application is getting and sending out, and that's why sometimes I prefer to deal with encoding myself and directly write/read byte arrays from the sockets. it's just a little bit more work, but it's well worth it when you take advantage of it to leave debug information in your application's log (even if it's just a dump into the Debug Stream) of exactly what you're dealing with.
For this, I've been using for the last couple of years this helper class to create a "hex dump" of the contents of a byte array:
///
/// Utility class to deal with
/// bytes and hexadecimal representations
///
public class HexUtil
{
///
/// Creates a hex dump of a byte array.
/// Useful for dumping protocol streams
///
///
Byte array to dump
///
Length of the array to read
///
Bytes per line to output in representation
///
public string BytesToHex(byte[] bytes, int length, int bytesPerLine)
{
if ( bytes == null || bytes.Length == 0 )
return "";
StringBuilder buffer = new StringBuilder("");
for ( int offset=0; offset < length; offset += bytesPerLine )
{
buffer.AppendFormat("{0:X8} ", offset);
int numBytes = Math.Min ( bytesPerLine, bytes.Length-offset);
// append all bytes in the line in hex
for ( int i=0; i < numBytes; i++ )
{
buffer.AppendFormat("{0:X2} ", bytes[offset+i]);
}
buffer.Append(new string(' ', ((bytesPerLine-numBytes)*3)+3));
for ( int i=0; i < numBytes; i++ )
{
buffer.Append(ByteToChar(bytes, offset+i));
}
// new line
buffer.Append(Environment.NewLine);
}
return buffer.ToString();
}
///
/// takes a byte from an array and returns
/// it's character representation.
///
///
/// If it's a visible ASCII character, returns it
/// otherwise returns '.'
///
///
byte array
///
offset of the byte to pick from array
///
protected char ByteToChar(byte[] b, int offset)
{
byte theByte = b[offset];
if ( theByte < 32 || theByte > 127 )
return '.';
char[] chars = Encoding.ASCII.GetChars(b,offset, 1);
return chars[0];
}
} // class HexUtil
It's nothing fancy, but it has saved my bacon more than once :)