Network communication through sockets is a welcome addition to the Windows Phone platform. Personally, I enjoy using those because of the tremendous performance gain compared to WCF services. One topic, however, seems to be rarely covered when it comes to TCP-based communication between the server (presumably running on a desktop machine) and the client (Windows Phone) = transmission of large amounts of data.
A lot of existing samples assume that the communication, although bi-directional, is done with small data units. For example, here is a pretty good sample that I used to build the asynchronous server. The reading callback looks like this:
It works perfectly fine on the desktop machine. I am also adding a terminator verification statement that allows me to check whether the whole data set was received:
Although seemingly simple, the data receiving process on a Windows Phone is handled in a different manner. There is no direct implementation ofSocket.BeginReceive. Instead, developers work with Socket.ReceiveAsync. Many samples give you this piece of code:
Notice the problem with this snippet. Once the string is received, that will be it. The inbound data length will be limited to the size of the buffer, and the maximum chunk size. The buffer size cannot always be fixed, and it is safe to assume that the developer does not want to allocate too much space for that in one iteration. The default socket chuck size cannot always be accommodated either.
The resolution comes in a continuous invocation of Socket.ReceiveAsync:
Here is where the terminator character plays a major role. Look at** if (dataFromServer.EndsWith(terminator)) –** that is the flag that shows whether more data is coming or not. With a receiving structure like I showed above, it is possible to keep receiving data until the connection is closed (happens all the time) or the terminator character is detected.
NOTE: If you are wondering what terminator character to use, try going with non-standard ones. For example, \u00BE. Otherwise, chances are that the actual “terminator” is not the terminating character.