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

  • By now you've likely heard of Agile development and building products in small incremental pieces, so you can get real feedback along the way. In fact, you may even be considering using Agile on your next project. But where do you start? Agile can take a lot of forms, such as Scrum or Kanban. Each form has advantages and disadvantages, but both will help your team get the right feedback they need to build great products. Read this white paper to find out which one is right for you.

  • Intelligent N+X Redundancy, Placement Affinities, & Future Proofing in the Virtualized Data Center Virtualization brought about the ability to simplify business continuity management in IT. Workload portability and data replication capabilities mean that physical infrastructure failures no longer need impact application services, and they can rapidly be recovered even in the event of complete site failure. However, Enterprises and Service Providers face new challenges ensuring they have enough compute …

Most Popular Programming Stories

More for Developers

RSS Feeds

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