×

Discussion Board

Results 1 to 10 of 10
  1. #1
    Regular Contributor
    Join Date
    Jan 2008
    Posts
    63

    problems receiving

    Hi, I've got an active object that have to receive from a device. I've used "reconeormore" but there is an error: Application closed:User 21 and ther's nothing written on the file.Does anybody know why?
    This is my code:

    void AO::RunL()
    {
    if(iStatus==KErrNone)
    {
    iSomeSocket.RecvOneOrMore(iBuffer,0,iStatus,iLen);
    file.Write(iBuffer);
    }
    }

  2. #2
    Registered User
    Join Date
    Apr 2005
    Location
    Barcelona
    Posts
    1,678

    Re: problems receiving

    Learning what a USER 21 panic is will help (hint: out of bounds). Check it out in the sdk doc.

  3. #3
    Regular Contributor
    Join Date
    Jan 2008
    Posts
    63

    Re: problems receiving

    thanks, but what does "out of bounds" mean?

  4. #4
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: problems receiving

    When you get the ten-millionth element of an array consisting of three items.

  5. #5
    Regular Contributor
    Join Date
    Jan 2008
    Posts
    63

    Re: problems receiving

    Thanks, i've understood what you've said but i don't know why i have this error, i don't get any array! why haven't I anything in the ibuffer?

  6. #6
    Registered User
    Join Date
    Apr 2005
    Location
    Barcelona
    Posts
    1,678

    Re: problems receiving

    You'd need to provide some more details (class definition for instance)
    In case the above snippet is writen as-is, then you're missing a SetActive() call. Once that request is completed, then it's safe to write the buffer contents into the file.

  7. #7
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Budapest, Hungary
    Posts
    28,572

    Re: problems receiving

    Quote Originally Posted by wask View Post
    This is my code:

    void AO::RunL()
    {
    if(iStatus==KErrNone)
    {
    iSomeSocket.RecvOneOrMore(iBuffer,0,iStatus,iLen);
    file.Write(iBuffer);
    }
    }
    OK, this is your code. But what is it supposed to do?
    In its current form:
    - "somehow" RunL starts running
    - it passes the descriptor to RecvOneOrMore (asynchronous)
    - and starts writing the contents of the same descriptor in a file
    SetActive is missing, but the real problem is that RecvOneOrMore sooner or later zeroes the length of iBuffer. So theoretically you are writing an empty descriptor to a file. However in practice the RecvOneOrMore may do this zeroing in a separate thread (in the server), establishing a race condition with RFile::Write (which in addition also involves IPC in the bacground).
    So it may happen that:
    1) File Server checks the length of the descriptor (say it contains Hello, and the length is 5)
    2) File Server allocates 5 bytes for Hello
    3) Socket Server zeroes the length of the descriptor
    4) File Server tries to read 5 bytes from the descriptor
    Ooops, by that time there are 0 bytes in the descriptor, and we have a USER 21 candidate.

  8. #8
    Regular Contributor
    Join Date
    Jan 2008
    Posts
    63

    Re: problems receiving

    Thanks for your reply.
    In fact my application is an active object that sends messages and then receives from a device. This part works fine, with "recvoneormore" function. But then i've tried to receive only without sending anything and it doesn't work. I have User 21 panic.
    this is my code:

    AO* AO::NewLC()
    {
    ObjetoActivo* result = new (ELeave) AO();
    CleanupStack::PushL( result );
    result->ConstructL();
    return result;
    }

    // -----------------------------------------------------------------------------
    AO::AO()
    : CActive( CActive::EPriorityStandard )
    {
    }

    // -----------------------------------------------------------------------------
    void AO::ConstructL()
    {
    User::LeaveIfError( socketServ.Connect() );
    CActiveScheduler::Add(this);
    RFs fsSession;
    User::LeaveIfError(fsSession.Connect());
    _LIT(KFileName, "C:\\wask.txt");

    TInt err=file.Open(fsSession,KFileName,EFileStream|EFileWrite|EFileShareAny);
    if (err==KErrNotFound) // file does not exist - create it
    {
    err=file.Create(fsSession,KFileName,EFileStream|EFileWrite|EFileShareAny);
    err=file.Open(fsSession,KFileName,EFileStream|EFileWrite|EFileShareAny);
    }

    }
    void AO::RunL()
    {
    if(iStatus==KErrNone)
    {
    iSomeSocket.RecvOneOrMore(iBuffer,0,iStatus,iLen);
    file.Write(iBuffer);
    SetActive();
    }
    }

  9. #9
    Nokia Developer Champion
    Join Date
    Jul 2004
    Posts
    2,015

    Re: problems receiving

    Reread what Wizard said.

    How does your RunL() get called in the first place?

    Why are you writing iBuffer to a file when you've just passed it to RecvOneOrMore()? dD you think RecvOneOrMore() will have filled iBuffer with some data after the function has returned?

    And regarding out of bounds, yes you are using an array, a descriptor is an array of characters.

  10. #10
    Regular Contributor
    Join Date
    Mar 2003
    Location
    Cambridge, Massachusetts, USA
    Posts
    87

    Lightbulb Re: problems receiving

    Quote Originally Posted by wask View Post
    void AO::RunL()
    {
    if(iStatus==KErrNone)
    {
    iSomeSocket.RecvOneOrMore(iBuffer,0,iStatus,iLen);
    file.Write(iBuffer);
    SetActive();
    }
    }
    wask, It appears that you do not yet have a clear understanding of active objects. Not to worry, the active object paradigm has proven to be a most difficult concept to explain - yet it is actually quite a simple mechanism. It helps to think of CActive as a Listener or Observer pattern for async functions - RunL gets called when there is a result from an async call.

    In your code you are supposed to call RecvOneOrMore from someplace else - maybe a StartL method? RecvOneOrMore is asynchronous so it returns immediately before anything is read. Later, after it has read some data into iBuffer, the active scheduler will call your RunL function. In RunL is where you handle the results of async function calls.

    A typical pattern looks like this:

    // Some other code, usually the owner of AO, will make the first call to StartReading.
    void AO::StartReading()
    {
    Cancel();
    iSomeSocket.RecvOneOrMore(iBuffer,0,iStatus,iLen);
    iMyAOState = EWaitingToRecvOneOrMore;
    SetActive();
    }

    void AO::RunL()
    {
    switch (iMyAOState) {
    case EWaitingToRecvOneOrMore:
    if(iStatus==KErrNone) file.Write(iBuffer);
    // now call StartReading again to wait for more data
    StartReading()
    break;
    }
    }
    I hope this makes sense.

Similar Threads

  1. Problems Sending and Receiving SMS Messages from the Emulator
    By appdeveloper in forum Mobile Java Networking & Messaging & Security
    Replies: 1
    Last Post: 2006-11-27, 05:15
  2. Several problems with NMIT 4.1 MMS
    By jtalviva in forum General Messaging
    Replies: 0
    Last Post: 2006-03-10, 11:03
  3. 5110 Sending and receiving SMS problems
    By firdoshg in forum PC Suite API and PC Connectivity SDK
    Replies: 0
    Last Post: 1970-01-01, 02:00

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •