×

Discussion Board

Results 1 to 10 of 10
  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    UDP Networking problem. Please help!

    Hi, I am trying to use UDP to send messages in a small mobile network. The aim is to have the messages be broadcast to everyone on the network (ie. 255.255.255.255). I want to be able to use the same class for both sending and receiving the messages, instead of a separate server and separate client class.

    Currently I am using active objects to schedule the read and write parts. I cannot, for the life of me, manage to send UDP packets over the network. I have no idea where I am going wrong. I have tried changing the broadcast addr to 0.0.0.0 - didn't work. Then setting the socket 'SendTo()' address to 255.255.255.255 and the 'Recv()' address to 0.0.0.0 (after reading some wiki howto for python networking) - didn't work. I thought maybe it was the set up of the socket. so i switched between using socket.connect and socket.bind commands - still didn't work. HELP! Below is the code I am using:
    Code:
    #include "Management/Broadcast/BroadcastManager.h"
    
    const TUint KSocketBufferSize = 256;
    const TInt KTimeOut = 50000000; 
    
    CBroadcastManager::CBroadcastManager( CLogger& aLog, RSocketServ& aSocketServer, RConnection& aConnection) 
    									: CActive( CActive::EPriorityStandard )
    	{
    	iLog = &aLog;
    	iSocketServer = &aSocketServer;
    	iConnection = &aConnection;
    	iLog->LogL(_L("Constructed broadcast manager"));
    	}
    
    void CBroadcastManager::ConstructL()
    	{
    	iBroadcastStatus = EBroadcastStarted;
    	
    	iLog->LogL(_L("Creating Timer active object"));
        iTimeOut = KTimeOut;
        iTimer = CBroadcastTimeOut::NewL(EPriorityHigh, *this);
        
        iLog->LogL(_L("Adding broadcast manager to the scheduler"));
    	CActiveScheduler::Add(this); // Add to scheduler
    	
    	iLog->LogL(_L("Opening UDP socket"));
    	TRAPD(err, iBroadcastSocket.Open(*iSocketServer, KAfInet, KSockDatagram, KProtocolInetUdp, *iConnection) );
    	if(err != KErrNone)
    	{
    		iLog->LogNumL(_L("Error opening broadcast socket"), err );
    	}
    	
    	iLog->LogL(_L("Creating read and write active objects"));
    	iBroadcastRead = CBroadcastRead::NewL(iBroadcastSocket, *iLog);
    	iBroadcastWrite = CBroadcastWrite::NewL(iBroadcastSocket, *iLog);
    	
    	iLog->LogL(_L("Finished constructing broadcast manager"));
    	}
    
    CBroadcastManager::~CBroadcastManager()
    	{
    		iBroadcastSocket.CancelAll();
    		delete iBroadcastRead;
    		delete iBroadcastWrite;
    		delete iTimer;
    		iBroadcastSocket.Close();
    	}
    
    void CBroadcastManager::DoCancel()
    // Cancel asychronous requests
        {
        iTimer->Cancel();
    
        // Cancel appropriate request to socket
        switch (iBroadcastStatus)
            {
    		case EBroadcastConnecting:
    			iBroadcastSocket.CancelConnect();
    			break;
    		default:
    			break;
            }
        }
    
    /*
     Connect to an Socket by IP address    
    */
    EXPORT_C void CBroadcastManager::ConnectL(TUint32 aAddr)
        {
        iLog->LogL(_L("Connecting to address"));
        // port number for test purposes - may need to be changed
        iAddress.SetPort(7000);
        iAddress.SetAddress(aAddr); 
        iAddress.SetFamily( KAfInet );
        
        iLog->LogL(_L("Connecting/binding broadcast socket to address"));
        //iBroadcastSocket.SetLocalPort(7000);
        TInt err = iBroadcastSocket.Connect(iAddress, iStatus));
     //   TInt err = iBroadcastSocket.Bind(iAddress));
    
        
        iBroadcastStatus = EBroadcastConnecting;
        iLog->LogL(_L("Setting active and timer"));
        SetActive();
        iTimer->After(iTimeOut);
        }
    
    /*
    Exported function wrapping call to iBroadcastWrite: writes character to socket
    */
    EXPORT_C void CBroadcastManager::Write(TChar aChar)
        {
         /* 
        In this simple implementation, if iBroadcastWrite is already active, ignore call.
        Full implementation would buffer data 
        */
        if ((iBroadcastStatus == EBroadcastConnected) && !iBroadcastWrite->IsActive()) {
            iLog->LogL(_L("Issuing SendTo to broadcast socket on 255.255.255.255"));
    			iBroadcastWrite->IssueSendTo(KInetAddrBroadcast, aChar);
        }
        }
    /*
    Exported function wrapping call to iBroadcastRead: reads character from socket
    */  
    EXPORT_C void CBroadcastManager::Read()
        {
    	if ((iBroadcastStatus == EBroadcastConnected)&&(!iBroadcastRead->IsActive())) {
    	    iLog->LogL(_L("Reading charachters from broadcast socket on 0.0.0.0"));
    			iBroadcastRead->IssueRecvFrom(KInetAddrAny);
    	}
        }
    
    /*
     Active object request complete handler.
     iBroadcastStatus flags what request was made, so its
     completion can be handled appropriately
    */
    void CBroadcastManager::RunL()
        {
        // Cancel TimeOut timer before completion
        iTimer->Cancel(); 
        _LIT(KConnecting,"\n<CBroadcastManager> Connecting\n");
        _LIT(KConnectionFailed,"\n<CBroadcastManager> Connection failed");
        _LIT(KDNSFailed,"\n<CBroadcastManager> DNS lookup failed");
        _LIT(KTimedOut,"\n<CBroadcastManager> Timed out\n");
        _LIT(KDomainName,"\nDomain name = ");
        _LIT(KIPAddress,"\nIP address = ");
        
        switch(iBroadcastStatus)
            {
        case EBroadcastConnecting:
            // IP connection request
            if (iStatus == KErrNone)
            // Connection completed sucessfully
                {
                iLog->LogL(KConnecting);
                iBroadcastStatus = EBroadcastConnected;
                Read(); //Start iBroadcastRead Active object 
                }
            else
                {
                iBroadcastStatus = EBroadcastConnectFailed;
                iLog->LogNumL(KConnectionFailed, iStatus.Int());
                }
            break;
        case EBroadcastTimedOut:
            // Timeout request
        	iLog->LogNumL(KTimedOut, KErrTimedOut);
            break;
        default:
        	break;
            };
        }
    
    /*
     Implements MTimeOutNotify: called when timeout expired
    */
    void CBroadcastManager::TimerExpired()
        {
        Cancel();
        
        iBroadcastStatus = EBroadcastTimedOut;
        TRequestStatus* status = &iStatus;   
        
        SetActive();
        User::RequestComplete(status, EBroadcastTimedOut);
        }
    
    /*
     Shutdown connection request
    */
    EXPORT_C void CBroadcastManager::Stop()
        {
        _LIT(KETerminate,"\n<CBroadcastManager> Terminating\n");
    
        iLog->LogL(KETerminate);
    
        switch (iBroadcastStatus)
            {
    		case EBroadcastConnected:
    			// Stop live connection
    			iBroadcastRead->Cancel();
    			iBroadcastWrite->Cancel();
    			break;
    		case EBroadcastConnecting:
    		default:
    			break;
            }
        }
    Code:
    #include "Management/Broadcast/BroadcastRead.h"
    
    
    void CBroadcastRead::ConstructL(RSocket& aSocket, CLogger& aLog)
    	{
    	iBroadcastSocket = &aSocket;
        iLog = &aLog;
        CActiveScheduler::Add(this);
    	}
    
    /*
     Cancel asychronous read request
    */
    void CBroadcastRead::DoCancel()
        {
        iBroadcastSocket->CancelRead();
        }
    
    /*
     Active object request complete handler
    */
    void CBroadcastRead::RunL()
        {
        if (iStatus == KErrNone)
            // Character has been read from socket
            {
            
    			iLog->LogL(_L("Received broadcast message "));
    			
    			_LIT(KDot,".");
    			iLog->LogL(KDot);
    			
    			TBuf16<1> Buffer;
    			Buffer.Copy(iBuffer);
    			iLog->LogL(Buffer);
    			
    			IssueRecvFrom(KInetAddrAny);
            }
        else
            {
    			// Error: pass it up to user interface
    			_LIT(KCEchoReadError,"\CBroadcastRead error");
    			iLog->LogNumL(KCEchoReadError, iStatus.Int());
            }   
        }
    
    void CBroadcastRead::IssueRecvFrom(TUint32 aAddr)
        {
        
        iAddress.SetPort(7000);
        iAddress.SetAddress(aAddr); 
        iAddress.SetFamily( KAfInet );
    
        iBroadcastSocket->RecvFrom(iBuffer,iAddress,NULL,iStatus);
        SetActive();
        };
    Code:
    #include "Management/Broadcast/BroadcastWrite.h"
    
    // 50 seconds time-out
    const TInt KTimeOut = 50000000; 
    
    void CBroadcastWrite::ConstructL(RSocket& aSocket, CLogger& aLog)
    	{
    	iBroadcastSocket = &aSocket;
    	iLog = &aLog;
        CActiveScheduler::Add(this);
    
        iTimeOut = KTimeOut; 
        iTimer = CBroadcastTimeOut::NewL(10, *this);
        iWriteStatus = EWaiting;
    	}
    
    /*
    Cancels asychronous write request
    */
    void CBroadcastWrite::DoCancel()
        {   
        iBroadcastSocket->CancelWrite();
        };
    
    /*
     Implements MTimeOutNotify: called when timeout expired
    */
    void CBroadcastWrite::TimerExpired()
        {
        Cancel();
        iWriteStatus = ETimedOut;
        TRequestStatus* status = &iStatus; 
        
        SetActive();
        User::RequestComplete(status, ETimedOut);
        }
    
    /*
     Active object request complete handler
    */
    void CBroadcastWrite::RunL()
        {
        if (iStatus == KErrNone)
            {
            _LIT(KWriteOperationTimedOut,"\nWrite operation timed out");
            switch(iWriteStatus)
                {
    			// Character has been written to socket
    			case ESending:
    				// Cancel TimeOut timer
    				iTimer->Cancel(); 
    				iWriteStatus = EWaiting;
    				break;
    			// Request timed out
    			case ETimedOut:
    				iLog->LogNumL(KWriteOperationTimedOut, KErrTimedOut);
    				break;
    			default:
    				break;
                };
            }
        else 
            {
            // Error: pass it up to user interface
            _LIT(KCEchoWriteError,"\CBroadcastWrite error");
            iLog->LogNumL(KCEchoWriteError, iStatus.Int());
            }
        }
    
    void CBroadcastWrite::IssueSendTo(TUint32 aAddr, const TChar &aChar)
        {
        // Set up buffer
        iBuffer.SetLength(0);
        iBuffer.Append(aChar);
        
        iAddress.SetPort(7000);
        iAddress.SetAddress(aAddr); 
        iAddress.SetFamily( KAfInet );
        
        iLog->LogL(_L("Sending broadcast message "));
        iBroadcastSocket->SendTo(iBuffer,iAddress,NULL,iStatus);
        
        // Request timeout
        iTimer->After(iTimeOut);
        
        iWriteStatus = ESending;
        SetActive();
        };

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: UDP Networking problem. Please help!

    According to the documentation Connect might do something on the sender side.
    But on the receiver side you certainly need Bind, to KInetAddrAny (which is 0.0.0.0) and your port (7000 as I see), then RecvFrom.
    On the sender side SendTo the same port and KInetAddrBroadcast (which is 255.255.255.255).

    The testing environment also matters: it will surely work in Ad-Hoc WLAN setting, it should work over infrastructure WLAN, and it may not work in the emulator when using the default WinSock stack. And it probably will not work in cellular networks.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    Re: UDP Networking problem. Please help!

    Hi, thanks for the quick reply.
    I have just tried to put a bind() before both SendTo and RecvFrom commands, using KInetAddrBroadcast and KInetAddrAny respectively. Still i am not getting anything. With regards to the connect() command, if I leave it out and just use Bind() then it seems the connection is never set active so when i call the functions Write() or Read() in my broadcast manager the line 'if ((iBroadcastStatus == EBroadcastConnected)&&(!iBroadcastRead->IsActive()))' if not fulfilled and so read/sending is never acheived.

    I am using nokia N80 S60 devices as tests in wifi ad-hoc mode. I have created the same access points on each device.

  4. #4
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: UDP Networking problem. Please help!

    What is in your log? N80 + Ad-Hoc WLAN should be fine, at least it worked for me in the past.

    Consider creating some linear counterpart of your code for testing purposes. Something like #4 in http://discussion.forum.nokia.com/fo...d.php?p=568785

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    Re: UDP Networking problem. Please help!

    Thanks for the tip. I tried to adapt the example you gave, but I kept getting errors. Anyway, I put KInetAddrLoop into my code for Connect(), SendTo() and RecvFrom() and it worked! Here is the output from my log. The message I have been trying to send is just the charachter '2'. I tried modifying my buffer length to handle a better string but the application kept crashing.

    Code:
    Initialising iBroadcastManager
    Creating Timer active object
    Adding broadcast manager to the scheduler
    Opening UDP socket
    Creating read and write active objects
    Finished constructing broadcast manager
    Finished constructing MobileNet AppUI
    Connecting to address KInetAddrLoop
    Connecting/binding broadcast socket to address
    Setting active and timer
    
    <CBroadcastManager> Connecting
    
    Ready to receive charachters from broadcast socket on KInetAddrLoop
    Binding broadcast socket to broadcast recv addr 
    Receiving broadcast messages... 
    Issuing SendTo to broadcast socket on KInetAddrLoop
    Binding broadcast socket to broadcast recv addr 
    Sending broadcast message 
    Received broadcast message ==>
    2
    Binding broadcast socket to broadcast recv addr 
    Receiving broadcast messages... 
    
    Issuing SendTo to broadcast socket on KInetAddrLoop
    Binding broadcast socket to broadcast addr 
    Sending broadcast message 
    Received broadcast message ==>
    2
    Binding broadcast socket to broadcast recv addr 
    Receiving broadcast messages... 
    
    ***AppUi: Clicked exit
    Stopping all connections
    
    <CBroadcastManager> Terminating
    So, if it working for localhost, why would it not be working for broadcast addresses?

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    Re: UDP Networking problem. Please help!

    Sorry, the program is still not working. Any combination of a broadcast address or KInetAny (0.0.0.0) address still does not let the program receive messages. Only the local host address (127.0.0.1) works. Please can someone give me some advice as to how to make N80's work with UDP? I hate to beg, but I need this to work for my final year project !

    Thanks in advance!

  7. #7
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,674

    Re: UDP Networking problem. Please help!

    BTW: Do you have NetworkServices capability?

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    Re: UDP Networking problem. Please help!

    Yes, NetworkServices has been included as a capability in the .mmp file

  9. #9
    Registered User
    Join Date
    Aug 2007
    Posts
    14

    Re: UDP Networking problem. Please help!

    At least the first posted code example seems to indicate a fundamental misunderstanding of the 'RecvFrom' functionality!

    Looks like you assume that the iAddress would specify the address/port from which to receive. However, whatever you put into this parameter before is totally ignored. The parameter is pure output parameter, which will contain the source address of the received packet when it has arrived.

    What the socket accepts is defined by the Bind call and in case of multicast, additional multicast join. To receive broadcast and multicast, you should bind to unspecified address (or 0.0.0.0, if you prefer to receive IPv4 only), and the port. SetLocalPort is the most appropriate call to use.

    At this point, I forget whether there was a need to set an additional socket option to allow incoming broadcasts.

    To receive actual multicast packets, you have to join the socket to multicast group with the socket option.

    The above is semantically same with any Posix socket implementations.

    Note: I'm not aware of recent developements, but possibly in emulator Ipv6 and multicast may only work with the real Symbian stack in use, winsock or other replacement stacks may not work.

    Note2: Binding to broadcast addresses (255.255.255.255) or any multicast address should never work. Such addresses are illegal as source address. Bind should return error (always remember to check the result of the Bind call!).
    Last edited by msa22; 2009-06-28 at 09:50.

  10. #10
    Regular Contributor
    Join Date
    May 2003
    Posts
    471

    Re: UDP Networking problem. Please help!

    Hi,

    1)The code you have posted is to long to read, if you want to pls post only the code when you setting the sockaddress and when you are calling to recvfrom and sendto.

    2) Use bind not connect

    Nahum

Similar Threads

  1. UDP socket Bind problem
    By inguvaseshu in forum Symbian Networking & Messaging (Closed)
    Replies: 4
    Last Post: 2006-06-21, 13:32
  2. UDP and SIP problem?
    By PrinceAlbertz in forum Symbian Networking & Messaging (Closed)
    Replies: 0
    Last Post: 2006-05-30, 13:10
  3. Series 90 WINS Emulator networking problem
    By redglove in forum Symbian Networking & Messaging (Closed)
    Replies: 1
    Last Post: 2004-11-01, 07:34
  4. networking problem on 7210 device / ssl
    By vizionari in forum Mobile Java Networking & Messaging & Security
    Replies: 4
    Last Post: 2003-04-18, 03:19

Posting Permissions

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