Dear All! Helps on RSock::RecvFrom

Login to reply to this topic.
Fri, 2005-03-04 10:07
Joined: 2005-02-26
Forum posts: 1
Hi, I am working on a SE P900.

I designed to establish data transmission between many PCs and P900s using UDP.

Firstly, I tried to use Multicast, but it seems it's still a technology in developing, not being supported, so far. Am I wrong? Can some experienced developer correct me about this?

Then, I choose to use simple send and receive. There is no problem for me to send msg to PC at all. However, I cannot receive any msg from PC. The code is below
==================================

CUdpRead::CUdpRead() : CActive(EPriorityStandard)
{
}

CUdpRead* CUdpRead::NewL(RSocket* aSocket, CGameUi* aAppUi)
{
   CUdpRead* self = NewLC(aSocket, aAppUi);
   CleanupStack::Pop();
   return self;
}

CUdpRead* CUdpRead::NewLC(RSocket* aSocket, CGameUi* aAppUi)
{
   CUdpRead* self = new(ELeave) CUdpRead;
   CleanupStack::PushL(self);
   self->ConstructL(aSocket, aAppUi);
   return self;
}

void CUdpRead::ConstructL(RSocket* aSocket, CGameUi* aAppUi)
{
   // Open a UDP socket
   //User::LeaveIfError(iUdpSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp));
   iUdpSocket = aSocket;   
   TInetAddr myLocalAddr;
   myLocalAddr.SetAddress(KInetAddrAny);
   myLocalAddr.SetPort(3025);
   User::LeaveIfError(iUdpSocket->Bind(myLocalAddr));
   User::InfoPrint(_L("UDP socket binded"));
   iAppUi      = aAppUi;
   CActiveScheduler::Add(this);
}

void CUdpRead::DoCancel()
{
   iUdpSocket->CancelRead();
}

void CUdpRead::IssueRead()         
{
   if (!IsActive())
   {
      TSockAddr anAddr;
      iUdpSocket->RecvFrom(iBuffer, anAddr, 0, iStatus);
      if(iStatus == KErrEof)
         User::InfoPrint(_L("UDP socket error"));
      else
      {
         User::InfoPrint(iStatusText);
      }
      SetActive();
   }
}

void CUdpRead::RunL()
{
   if (iStatus == KErrNone)   // Character has been read from socket
   {
      iStatusText.Copy(iBuffer);
      //User::InfoPrint(iStatusText);
      
      iAppUi->HandleIncomingPacket(iStatusText);
      
      IssueRead();
   }
   else
   {
      iStatusText=_L("\nError reading from socket");
      User::InfoPrint(iStatusText);
   }   
}
=========================================

There is no problem at either Bind() or construct the socket. No error msg at all.
Also, I put a User::InfoPrint() once any msg is received, it never happens.

So, could any friend help me about this?

It's said that, the phone is sitting behind router, which is applied by server. As a result, PC cannot get the actual IP of the phone. Hence, any data packets cannot be send to the correct IP address. If it's true, is there any easier way to help this case? I know that portmapping skills exist for PC, is there any for phone?

Thanks!

Regards
Chaosy

Tue, 2005-06-14 11:27
Joined: 2005-05-09
Forum posts: 33
Re: Dear All! Helps on RSock::RecvFrom

   RecvFrom is non blocking statement so User::InfoPrint() will never encounter i think

u should use some notifier class to deal with received messages, I am not experienced professional let us wait for replies
Tue, 2005-06-14 13:01
Joined: 2005-02-14
Forum posts: 13
Re: Dear All! Helps on RSock::RecvFrom
I think you have a couple of problems here. 

First, you have to decide if your app is a server or a client.  All apps must connect to the socket server, then open a socket.  Server apps then use Bind() followed by Listen().  When a connection is made, servers create a second, new socket and tie that connection to the new socket by using Accept(). 

A client app uses Connect() to connect to a server side.

After an Accept() or a Connect(), SendTo() or Write() (for output) or RecvFrom() or Read() or Recv() (for input) can be used.

Your second issue is that you are not using the concept of an Active Object in Symbian OS correctly.  You have to do one of two things with calls like RecvFrom(): either follow then with User::WaitForResponse() or immediately use a SetActive() call and rely on the system to respond.  If you use SetActive(), then your RunL() definition will be called each time an I/O call returns -- in your case, when RecvFrom() returns.  You seem to get the RunL() idea right, but you will not get a correct status returned from your RecvFrom() call in IssueRead().  The status variable is only assured when the RunL() is called. 

Now...having written that, I share your frustration.  I follow my own description above, and I cannot get RecvFrom() to actually pick up data.  I know data arrives (I can track it through a packet sniffer), but my RecvFrom() never returns to RunL().  So...if you actually get this to work, let's continue the conversation.

- F
  • Login to reply to this topic.