Click here to Skip to main content
6,594,932 members and growing! (16,743 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Mobile Development » General     Intermediate

Reading given number of bytes with RSocket::Read()

By luweiewul

Exploring how to read given number of bytes with RSocket::Read() on Symbian.
C++, eVC 4.0, Windows, Win Mobile, Visual Studio, Dev
Posted:14 Jul 2005
Views:18,982
Bookmarked:9 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
3 votes for this article.
Popularity: 0.72 Rating: 1.50 out of 5
2 votes, 66.7%
1

2

3
1 vote, 33.3%
4

5

Introduction

If your network Symbian program just blocks forever mysteriously, or you just want a simple piece of code to demonstrate how to use socket in Symbian. This story is for you.

The expedition

Very often, we want to read a given number of bytes from a network when, for example, the message body length is known after reading the header. Symbian RSocket provides two groups of reading methods, RecvOneOrMore() with a scheme for reading some and returning as soon as possible and Recv()/Read() with a scheme for blocking until the maximum length of the buffer descriptor is fully filled. Both the schemes can fulfill our requirement. With RecvOneOrMore, we can make a loop to keep reading and counting the returned bytes until the sum is not less than the desired message length. Obviously, this method is not efficient enough. We may prefer to allocate a descriptor with a given maximum length and use Recv()/Read() to get the work done in one call. The example is as follows:

    RSocketServ socketServ;
    RSocket socket;
    RSocket listener;
    User::LeaveIfError(socketServ.Connect());
    CleanupClosePushL(socketServ);
    User::LeaveIfError(listener.Open(socketServ, 
              KAfInet,KSockStream, KProtocolInetTcp));
    User::LeaveIfError(listener.SetLocalPort(80));  
    User::LeaveIfError(listener.Listen(1));
    TRequestStatus status;
    TBuf8<256> buffer;
    socket.Open(socketServ);
    listener.Accept(socket, status); 
    User::WaitForRequest(status);
    ......
    TBuf8<256>data;
    socket.Read(data,status);
    User::WaitForRequest(status);
    ......

The listener object listens at port 80, once an incoming connection is accepted; another RSocket object socket reads the data from the network as shown in the last three lines. Here, 256 bytes are read before the code can continue.

This is not the end of the story because while we are coding, we usually have no idea if it must be 256. The number of bytes to be read can be known only at run time. But the size of the stack based descriptor TBuf must be set before compilation. Unfortunately, I couldn't find any piece of example code that solves this problem in SDK document or Google. I tried to use the heap based alternative, HBufC, whose size can be set at run time. HBufC is not modifiable. But RSocket::Read method requires a modifiable descriptor. This can be overcome by using the method HBufC::Des(). This gives a good introduction to the Symbian descriptor system. The code is modified as follows:

    TPtr8 gDataPtr(NULL,0);
    UInt32 msglen;
    //... assign value to msglen ...

    HBufC8* buffer = HBufC8::NewL(msglen);
    gDataPtr.Set(buffer->Des());
    socket.Read(gDataPtr,status);
    User::WaitForRequest(status);

It works as expected. But is it correct? I thought so before it took me a whole day to find out why sometimes the program just blocks forever. For example, when the value of msglen is 137 and when you check buffer->Des().MaxLength() of the newly allocated buffer, you get a value of 140! The RSocket::Read method checks only the MaxLength and tries to fill it. It keeps waiting for the 3 bytes that never exist even when the desired 137 bytes have already been received.

Why the MaxLength is 140 and not 137? Because �the maximum length of the heap cell in which the HBufC was allocated is used to set the maximum length of the returned TPtr", as Tip9 of descriptor-tips says. The size of the heap cell only guarantees that it can contain the size given by the user, but not equal to it! 137 is not word-aligned, so the system allocates 140 instead.

I can�t imagine that the Symbian descriptor system doesn�t provide any solution for such a simple problem to the RSocket::Read�s requirement. However, I am too exhausted to dig for it. I finally chose a non-Symbian favour by maintaining a C-style array.

    TUint8 *buf=new TUint8[msglen];
    gDataPtr.Set(buf,0,msglen);
    blank.Read(gDataPtr,status);
    User::WaitForRequest(status);

Of course, now I have to take care of releasing the array space myself.

I'll appreciate if any Symbian expert can give us an official solution. My expedition has to stop here before I can�t help deleting my Symbian SDK and install double copies of Java and .NET.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

luweiewul


Member

Location: Germany Germany

Other popular Mobile Development articles:

  • Writing Your Own GPS Applications: Part 2
    In part two of the series, the author of "GPS.NET" teaches developers how to write GPS applications suitable for the real world by mastering GPS precision concepts. Source code includes a working NMEA interpreter and sample high-precision application in C# and VB.NET.
  • Writing Your Own GPS Applications: Part I
    What is it that GPS applications need to be good enough to use for in-car navigation? Also, how does the process of interpreting GPS data actually work? In this three-part series, I will cover both topics and give you the skills you need to write a commercial-grade GPS application.
  • Learn How to Find GPS Location on Any SmartPhone, and Then Make it Relevant
    A step by step tutorial for getting GPS from any SmartPhone, even without GPS built in, and then making location useful.
  • iPhone UI in Windows Mobile
    It's an interface that works with transparency effects. As a sample I used an interface just like the iPhone one. In this tutorial I am explaining how simple is working with transparency on Windows Mobile.
  • Pocket 1945 - A C# .NET CF Shooter
    An article on Pocket PC game development
Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 1 of 1 (Total in Forum: 1) (Refresh)FirstPrevNext
Generalmaybe you are right Pinmemberwaynechen23:59 19 Sep '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 14 Jul 2005
Editor: Rinish Biju
Copyright 2005 by luweiewul
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project