Receiving & Converting Numeric and String Data via Sockets

Many times, a remote system will send a numeric value indicating the length of the data to be received in subsequent receive commands. However, when you start sending and receiving numeric data via sockets, you have to be aware of conversion issues in terms of what type of machine is on the other end of the connection. Specifically, you need to know how to convert numeric data from the local machine's format (host order) to the industry standard format for sending sockets data (network order).

Note: If the terms host order, network order, little-endian, or big-endian are new to you or you'd like a refresher on these terms, please refer to my article entitled "Sockets Byte-Ordering Primer".

Use the IPAddress.NetworkToHostOrder method to convert data from network order to the host order (local machine format). To illustrate its use, here is a ReceiveHeader function where I'm performing the following tasks:

  • Receive the data from the remote machine via the Socket.Receive method.
  • Verify that the bytes received are exactly 4.
  • The Socket.Receive method returns a byte array so the sample converts that into a numeric value, using the BitConvert.ToInt32 method.
  • Finally, the IPAddress.NetworkToHostOrder method converts the length value to the host order.
public int ReceiveHeader(Socket socket)
{
   int dataSize = -1;    // error
   byte [] buffer = new byte[4];

   int bytesRead = socket.Receive(buffer, 4,
                   System.Net.Sockets.SocketFlags.None);

   if (4 == bytesRead)
   {
      dataSize = BitConverter.ToInt32(buffer, 0);
      dataSize = IPAddress.NetworkToHostOrder(dataSize);
   }
   else    // error condition

   return dataSize;
}

Now, let's look at how to receive string data from a remote machine with multiple reads where each string is to be concatenated. In this case, there are no issues of little-endian vs. big-endian as that pertains to numeric data conversion. Instead, you may have a situation where you need to convert from a byte buffer to a String object. You can execute the conversion by using either the ASCIIEncoding or UnicodeEncoding classes depending on your needs. In the ReceiveDetail function, I perform the following steps (remember that this function was called after the ReceiveHeader function from the previous section. Therefore, the datasize value was retrieved from that function.):

  • From a while loop, call Socket.Receive until no bytes are returned. The data is read into a byte array.
  • Instantiate an ASCIIEncoding object.
  • Call the ASCIIEncoding.GetString value to convert the byte array into a String object and then concatenate that value with the previously read data.
public string ReceiveDetail(Socket socket, byte[] buffer,
                            int dataSize)
{
   string response = "";

   int bytesReceived         = 0;
   int totalBytesReceived    = 0;
   while (0 < (bytesReceived = 
          socket.Receive(buffer, (dataSize - totalBytesReceived),
                                  SocketFlags.None)))
   {
      totalBytesReceived += bytesReceived;
      ASCIIEncoding encoding = new ASCIIEncoding();
      response += encoding.GetString(buffer, 0, bytesReceived);
   }

   return response;
}


About the Author

Tom Archer - MSFT

I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers. Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.

Comments

  • problem regarding object conversion

    Posted by Bishan on 06/05/2015 04:14am

    Sir, I am facing a problem. Actually i want to send a structure to the network. structure should be in the defined format. But In C# there is issue with the size of data types. In C# char is of 2 bytes but i have to send it in a byte. Second problem is of big or little endian format. Please try to resolve the issue. Thanks.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Bonita BPM 7 is here! And for you, an in-depth tour of its innovation. In this webinar, we'll guide you through the brand-new features of this release and demonstrate them live. You will: Discover how business application implementation and maintenance is now even easier, with decoupling of process logic, business data and user interface Learn how to create "living applications" for business processes which present business data in custom views We recommend that you watch the half-hour recording of our …

  • The nature of the financial services industry places a myriad of international compliance requirements on a company's IT team, as well as an expectation by its customers to deliver the high test levels of performance and reliability. To survive and thrive, businesses in the industry must not only keep pace with customer demand but gain competitive advantage. Those demands mean the IT team must be at the forefront of adopting emerging technologies

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date