« FixEncoding Pipeline Component v1.0.0.1 | Main | WCF Security Article »
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:
/// <summary>
/// Utility class to deal with
/// bytes and hexadecimal representations
/// </summary>
public class HexUtil
{
/// Creates a hex dump of a byte array.
/// Useful for dumping protocol streams
/// <param name="bytes">Byte array to dump</param>
/// <param name="length">Length of the array to read</param>
/// <param name="bytesPerLine">Bytes per line to output in representation</param>
/// <returns>Hexadecimal representation</returns>
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));
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.
/// <remarks>
/// If it's a visible ASCII character, returns it
/// otherwise returns '.'
/// </remarks>
/// <param name="b">byte array</param>
/// <param name="offset">offset of the byte to pick from array</param>
/// <returns>character representation</returns>
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 :)
Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...
email: tomas@winterdom.com msn: tomasr@passport.com
Copyright © 2002-2008, Tomas Restrepo.
Powered by: newtelligence dasBlog 2.2.8279.16125