Boy, Dog, Source Code

This blog entry is taking care of business. The picture has nothing to do with the blog entry. The pic is of a boy on the fast ferry to one of the out islands in this island paradise. It was his birthday, and he got the puppy for his birthday. The Lovely One and I were enchanted with this little boy, and the obvious love that he had for the puppy.

When I first started writing this blog, I said that I might post some source code. This is my first source code posting. I am putting it up as a thank you for all of the other code snippets that I personally have benfited from, that my fellow geeks posted on the web.

Writing this was particularly time consuming because Google doesn't return any obvious results for find out (using Visual Studio 2008 professional), C#, Windows Mobile SDK for Smart Devices and such. Normally I program in C++, but I had to use C# to integrate with other C# code that was written for this project.

Okay, what happens is that the device accumulates data, and I have to send this data over the network using ftp. If I went directly to connect to the server, and the server was not up, then the application would lock waiting for the timeout on the ftp side. The lock was intentional, because I did not want other threads operating on the file that I was going to upload. Since the timeout is real long, I would like to collect data in the meantime. To avoid this, before I try to connect to the FTP server, I want to see if it is alive. WindowsCE does not have the ping function built in.

I do this in a method shown below that requires a custom packet class to send to the ftp server. If the server responds, Bob's yer uncle. I don't bother processing the response. The code is quite simple, and if you need explanation, use the comments.


///////////////////// *********** Check out (ftp) Server
///
/// checkOutServer
///

/// returns a boolean to indicated that a successful ping was returned
/// due to the lack of a ping utility in WindowsCE, I had to put one together.
/// Essentially, I have a custom ICMP class (see below) which generates a packet
/// to send to the server. I send the packet to the server, and if the server
/// responds, I set a boolean to true and return it, indicating that the ftp server
/// is alive.


public bool checkOutServer()
{
bool fsf = false;
byte[] data = new byte[1024];
int recv;
Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("put in IP address string"), 0);
EndPoint ep = (EndPoint)iep;
ICMP packet = new ICMP();
packet.Type = 0x08;
packet.Code = 0x00;
packet.Checksum = 0;
Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 0, 2);
Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 2, 2);
data = Encoding.ASCII.GetBytes("test packet");
Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
packet.MessageSize = data.Length + 4;
int packetsize = packet.MessageSize + 4;
UInt16 chcksum = packet.getChecksum();
packet.Checksum = chcksum;
host.SendTo(packet.getBytes(), packetsize, SocketFlags.None, iep);
try
{
data = new byte[1024];
recv = host.ReceiveFrom(data, ref ep);
ftpServerIsAlive = true;
host.Close();
return ftpServerIsAlive;
}
catch (SocketException bb)
{
string conn = bb.Message;


//I have to invoke a delegate because this is run in a separate


//thread that does not have access to the Form
this.Invoke(new textStatusDelegate(textStatus), new Object[] { conn });
ftpServerIsAlive = false;
return fsf;
}
}
} //public partial class





//this is the classfile that creates the packet to send out to the server
class ICMP
{
public byte Type;
public byte Code;
public UInt16 Checksum;
public int MessageSize;
public byte[] Message = new byte[1024];
public ICMP()
{
}
public ICMP(byte[] data, int size)
{
Type = data[20];
Code = data[21];
Checksum = BitConverter.ToUInt16(data, 22);
MessageSize = size - 24;
Buffer.BlockCopy(data, 24, Message, 0, MessageSize);
}
public byte[] getBytes()
{
byte[] data = new byte[MessageSize + 9];
Buffer.BlockCopy(BitConverter.GetBytes(Type), 0, data, 0, 1);
Buffer.BlockCopy(BitConverter.GetBytes(Code), 0, data, 1, 1);
Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, data, 2, 2);
Buffer.BlockCopy(Message, 0, data, 4, MessageSize);
return data;
}
public UInt16 getChecksum()
{
UInt32 chcksm = 0;
byte[] data = getBytes();
int packetsize = MessageSize + 8;
int index = 0;
while (index < color="#336666">Convert.ToUInt32(BitConverter.ToUInt16(data, index));
index += 2;
}
chcksm = (chcksm >> 16) + (chcksm & 0xffff);
chcksm += (chcksm >> 16);
return (UInt16)(~chcksm);
}
}
}

No comments: