Chat Client/Server Part 3: The Connection Class
Receiving Data
Now we get to the portion where we read data from the network stream and build a meaningful packet from it. Our Connection class is going to have a function called ReceiveData() which will take a stream of bytes it receives and interprets them.
Let’s begin our function.
1 2 3 4 5 6 7 | public Packet ReceiveData() { NetworkStream ns = c.GetStream(); Packet p = null; if (c.Connected && ns.DataAvailable) { |
Here we have our header and first few lines of the ReceiveData function. This function will first check to see if there is an active connection, and if that connection has an data available. If either of these are false, then we will just return null later on in the function. This means that ReceiveData should be polled periodically to see if data can be read.
Let’s continue.
1 2 3 4 5 6 | // get packet type byte[] packetType = new byte[4]; byte[] packetLength = new byte[4]; byte[] packetdata = null; int size = 0; |
As you can see, I build some byte arrays here. These arrays will be used to pull from bytes from the front of the packet. If you can remember from our SendData function earlier, before we ever sent any data we sent some bytes which were the length of the packet and the type of the packet. That is what these bytes will read in.
The packetdata byte array will be the main data from our packet. It is declared here as null because we don’t know how large our packet will be until we read in its size. The size integer we declare is going to hold that value.
1 2 3 4 5 6 7 | ns.Read(packetType, 0, 4); ns.Read(packetLength, 0, 4); size = BitConverter.ToInt32(packetLength, 0); packetdata = new byte[size]; ns.Read(packetdata, 0, size); |
Here is the flesh of the function. First we read in the 4 bytes which will tell us the type of packet (an integer.) Then we read in the length of the packet (also an integer.) That length is then converted into an integer and stored in the size value.
That’s when we allocate memory for the data in the packet, and read in that data from the stream. Easy!
So now that we have our packet data, we need to convert it into something meaningful to the rest of our program. We have to interpret the packet type.
1 2 3 4 5 6 7 8 | if (BitConverter.ToInt32(packetType, 0) == 1) { p = ChatPacket.Parse(packetdata); } } return p; } |
Here we have an if which determines the type of packet we are receiving, based upon the information received in our header. In this program, we only have one type of packet. If we had more, then our if would be larger here. If you will have many types of packets, a more efficient means of determining the packet type will be needed.
1 2 3 4 5 6 7 8 9 10 11 | public void Close() { if (c != null) { c.Client.Close(); c.Close(); c = null; } } } } |
Here we have the end of our connection class. We close it out with a Close() function which will shutdown the connection.
That concludes our connection class. In the next tutorial, we will write our server!
Follow Dave on Twitter
