Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes

UDPSocket Class Reference

#include <UDPSocket.h>

List of all members.

Classes

class  CallbackInterface

Public Types

enum  State { NOT_BOUND, BOUND }

Public Member Functions

 UDPSocket ()
 ~UDPSocket ()
int getSocketId () const
void setUserId (int userId)
int getUserId () const
int getState ()
Getter functions

IPvXAddress getLocalAddress ()
int getLocalPort ()
Opening and closing connections, sending data

void setOutputGate (cGate *toUdp)
void bind (int localPort)
void bind (IPvXAddress localAddr, int localPort)
void connect (IPvXAddress remoteAddr, int remotePort)
void setMulticastInterfaceId (int interfaceId)
int getMulticastInterfaceId () const
void sendTo (cMessage *msg, IPvXAddress destAddr, int destPort)
void send (cMessage *msg)
void close ()

Static Public Member Functions

static const char * stateName (int state)
static int generateSocketId ()

Protected Member Functions

void sendToUDP (cMessage *msg)

Protected Attributes

int sockId
int usrId
int sockstate
IPvXAddress localAddr
int localPrt
IPvXAddress remoteAddr
int remotePrt
int mcastIfaceId
CallbackInterfacecb
void * yourPtr
cGate * gateToUdp

Handling of messages arriving from UDP



bool belongsToSocket (cMessage *msg)
void setCallbackObject (CallbackInterface *cb, void *yourPtr=NULL)
void processMessage (cMessage *msg)
static bool belongsToAnyUDPSocket (cMessage *msg)

Detailed Description

UDPSocket is a convenience class, to make it easier to manage TCP connections from your application models. You'd have one (or more) UDPSocket object(s) in your application simple module class, and call its member functions (bind(), listen(), connect(), etc.) to open, close or abort a TCP connection.

UDPSocket chooses and remembers the sockId for you, assembles and sends command packets (such as OPEN_ACTIVE, OPEN_PASSIVE, CLOSE, ABORT, etc.) to TCP, and can also help you deal with packets and notification messages arriving from TCP.

A session which opens a connection from local port 1000 to 10.0.0.2:2000, sends 16K of data and closes the connection may be as simple as this (the code can be placed in your handleMessage() or activity()):

   UDPSocket socket;
   socket.connect(IPvXAddress("10.0.0.2"), 2000);
   msg = new cMessage("data1");
   msg->setByteLength(16*1024);  // 16K
   socket.send(msg);
   socket.close();
 

Dealing with packets and notification messages coming from TCP is somewhat more cumbersome. Basically you have two choices: you either process those messages yourself, or let UDPSocket do part of the job. For the latter, you give UDPSocket a callback object on which it'll invoke the appropriate member functions: socketEstablished(), socketDataArrived(), socketFailure(), socketPeerClosed(), etc (these are methods of UDPSocket::CallbackInterface)., The callback object can be your simple module class too.

This code skeleton example shows how to set up a UDPSocket to use the module itself as callback object:

 class MyModule : public cSimpleModule, public UDPSocket::CallbackInterface
 {
    UDPSocket socket;
    virtual void socketDataArrived(int sockId, void *yourPtr, cPacket *msg, bool urgent);
    virtual void socketFailure(int sockId, void *yourPtr, int code);
    ...
 };
 void MyModule::initialize() {
    socket.setCallbackObject(this,NULL);
 }
 void MyModule::handleMessage(cMessage *msg) {
    if (socket.belongsToSocket(msg))
       socket.processMessage(msg);
    else
       ...
 }
 void MyModule::socketDatagramArrived(int, void *, cMessage *msg, UDPControlInfo *ctrl) {
     ev << "Received UDP packet, " << msg->getByteLength() << " bytes\\n";
     delete msg;
 }
 void MyModule::socketPeerClosed(int, void *, int code) {
     ev << "Socket peer closed!\\n";
 }
 

If you need to manage a large number of sockets, the UDPSocketMap class may be useful.

See also:
UDPSocketMap

Definition at line 98 of file UDPSocket.h.


Member Enumeration Documentation

Enumerator:
NOT_BOUND 
BOUND 

Definition at line 117 of file UDPSocket.h.

{NOT_BOUND, BOUND};  // FIXME needed?


Constructor & Destructor Documentation

UDPSocket::UDPSocket (  ) 

Constructor. The getSocketId() method returns a valid Id right after constructor call.

Definition at line 21 of file UDPSocket.cc.

{
    // don't allow user-specified sockIds because they may conflict with
    // automatically assigned ones.
    sockId = generateSocketId();
    usrId = -1;
    sockstate = NOT_BOUND;

    localPrt = remotePrt = 0;
    mcastIfaceId = -1;
    cb = NULL;
    yourPtr = NULL;

    gateToUdp = NULL;
}

UDPSocket::~UDPSocket (  )  [inline]

Destructor

Definition at line 148 of file UDPSocket.h.

{}


Member Function Documentation

bool UDPSocket::belongsToAnyUDPSocket ( cMessage *  msg  )  [static]

Returns true if the message belongs to any UDPSocket instance. (This basically checks if the message has an UDPControlInfo attached to it as getControlInfo().)

Definition at line 173 of file UDPSocket.cc.

{
    return dynamic_cast<UDPControlInfo *>(msg->getControlInfo());
}

bool UDPSocket::belongsToSocket ( cMessage *  msg  ) 

Returns true if the message belongs to this socket instance (message has a UDPControlInfo as getControlInfo(), and the sockId in it matches that of the socket.)

Definition at line 167 of file UDPSocket.cc.

{
    return dynamic_cast<UDPControlInfo *>(msg->getControlInfo()) &&
           ((UDPControlInfo *)(msg->getControlInfo()))->getSockId()==sockId;
}

void UDPSocket::bind ( int  localPort  ) 

Bind the socket to a local port number. Use port=0 for ephemeral port.

Definition at line 70 of file UDPSocket.cc.

Referenced by LDP::initialize().

{
    if (sockstate!=NOT_BOUND)
        opp_error("UDPSocket::bind(): socket already bound");
    if (lPort<=0 || lPort>65535)
        opp_error("UDPSocket::bind(): invalid port number %d", lPort);

    localPrt = lPort;

    UDPControlInfo *ctrl = new UDPControlInfo();
    ctrl->setSockId(sockId);
    ctrl->setUserId(usrId);
    ctrl->setSrcPort(localPrt);
    cMessage *msg = new cMessage("BIND", UDP_C_BIND);
    msg->setControlInfo(ctrl);
    sendToUDP(msg);

    sockstate = BOUND;
}

void UDPSocket::bind ( IPvXAddress  localAddr,
int  localPort 
)

Bind the socket to a local port number and IP address (useful with multi-homing or multicast addresses). Use port=0 for an ephemeral port.

Definition at line 90 of file UDPSocket.cc.

{
    if (sockstate!=NOT_BOUND)
        opp_error("UDPSocket::bind(): socket already bound");
    if (lPort<=0 || lPort>65535)
        opp_error("UDPSocket::bind(): invalid port number %d", lPort);

    localAddr = lAddr;
    localPrt = lPort;

    UDPControlInfo *ctrl = new UDPControlInfo();
    ctrl->setSockId(sockId);
    ctrl->setUserId(usrId);
    ctrl->setSrcAddr(localAddr);
    ctrl->setSrcPort(localPrt);
    cMessage *msg = new cMessage("BIND", UDP_C_BIND);
    msg->setControlInfo(ctrl);
    sendToUDP(msg);

    sockstate = BOUND;
}

void UDPSocket::close (  ) 

Unbinds the socket. There is no need for renewSocket() as with TCPSocket.

Definition at line 154 of file UDPSocket.cc.

{
    if (sockstate!=BOUND)
        return;

    cMessage *msg = new cMessage("UNBIND", UDP_C_UNBIND);
    UDPControlInfo *ctrl = new UDPControlInfo();
    ctrl->setSockId(sockId);
    msg->setControlInfo(ctrl);
    sendToUDP(msg);
    sockstate = NOT_BOUND;
}

void UDPSocket::connect ( IPvXAddress  remoteAddr,
int  remotePort 
)

Connects to a remote UDP socket. This has two effects: (1) this socket will only receive packets from specified address/port, and (2) you can use send() (as opposed to sendTo()) to send packets.

Definition at line 112 of file UDPSocket.cc.

{
    if (sockstate!=BOUND)
        opp_error( "UDPSocket::connect(): socket must be bound before connect() can be called");
    if (addr.isUnspecified())
        opp_error("UDPSocket::connect(): unspecified remote address");
    if (port<=0 || port>65535)
        opp_error("UDPSocket::connect(): invalid remote port number %d", port);

    remoteAddr = addr;
    remotePrt = port;

    UDPControlInfo *ctrl = new UDPControlInfo();
    ctrl->setSockId(sockId);
    ctrl->setDestAddr(remoteAddr);
    ctrl->setDestPort(remotePrt);
    cMessage *msg = new cMessage("CONNECT", UDP_C_CONNECT);
    msg->setControlInfo(ctrl);
    sendToUDP(msg);
}

int UDPSocket::generateSocketId (  )  [static]

Generates a new socket id.

Definition at line 50 of file UDPSocket.cc.

Referenced by SCTP::bindPortForUDP(), UDPAppBase::bindToPort(), RTP::createSocket(), RTCP::createSocket(), and UDPSocket().

{
    return ev.getUniqueNumber();
}

IPvXAddress UDPSocket::getLocalAddress (  )  [inline]

Definition at line 185 of file UDPSocket.h.

{return localAddr;}

int UDPSocket::getLocalPort (  )  [inline]

Definition at line 186 of file UDPSocket.h.

{return localPrt;}

int UDPSocket::getMulticastInterfaceId (  )  const [inline]

Returns the output interface for sending multicast packets.

Definition at line 226 of file UDPSocket.h.

{return mcastIfaceId;}

int UDPSocket::getSocketId (  )  const [inline]

Returns the internal socket Id.

Definition at line 153 of file UDPSocket.h.

{return sockId;}

int UDPSocket::getState (  )  [inline]

Returns the socket state, one of NOT_BOUND, BOUND, etc. Messages received from UDP must be routed through processMessage() in order to keep socket state up-to-date.

Definition at line 171 of file UDPSocket.h.

{return sockstate;}

int UDPSocket::getUserId (  )  const [inline]

Returns the userId.

Definition at line 164 of file UDPSocket.h.

{return usrId;}

void UDPSocket::processMessage ( cMessage *  msg  ) 

Examines the message (which should have arrived from UDP), and if there is a callback object installed (see setCallbackObject(), class CallbackInterface), dispatches to the appropriate method of it with the same yourPtr that you gave in the setCallbackObject() call.

IMPORTANT: for performance reasons, this method doesn't check that the message belongs to this socket, i.e. belongsToSocket(msg) would return true!

Definition at line 184 of file UDPSocket.cc.

{
    UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
    ASSERT(ctrl->getSockId()==sockId);

    switch (msg->getKind())
    {
        case UDP_I_DATA:
             if (cb)
                 cb->socketDatagramArrived(sockId, yourPtr, msg, ctrl);
             else {
                 delete msg;
                 delete ctrl;
             }
             break;
        case UDP_I_ERROR:
             sockstate = NOT_BOUND;
             delete msg;
             if (cb)
                 cb->socketPeerClosed(sockId, yourPtr);
             break;
        default:
             opp_error("UDPSocket: invalid msg kind %d, one of the UDP_I_xxx constants expected", msg->getKind());
    }
}

void UDPSocket::send ( cMessage *  msg  ) 

Sends a data packet to the address and port specified previously in a connect() call.

Definition at line 147 of file UDPSocket.cc.

Referenced by sendToUDP().

{
    if (remoteAddr.isUnspecified() || remotePrt==0)
        opp_error("UDPSocket::send(): must call connect() before using send()");
    sendTo(msg, remoteAddr, remotePrt);
}

void UDPSocket::sendTo ( cMessage *  msg,
IPvXAddress  destAddr,
int  destPort 
)

Sends a data packet to the given address and port.

Definition at line 133 of file UDPSocket.cc.

Referenced by send(), and LDP::sendHelloTo().

{
    msg->setKind(UDP_C_DATA);
    UDPControlInfo *ctrl = new UDPControlInfo();
    ctrl->setSockId(sockId);
    ctrl->setSrcAddr(localAddr);
    ctrl->setSrcPort(localPrt);
    ctrl->setDestAddr(destAddr);
    ctrl->setDestPort(destPort);
    ctrl->setInterfaceId(mcastIfaceId);
    msg->setControlInfo(ctrl);
    sendToUDP(msg);
}

void UDPSocket::sendToUDP ( cMessage *  msg  )  [protected]

Definition at line 55 of file UDPSocket.cc.

Referenced by bind(), close(), connect(), and sendTo().

{
    if (!gateToUdp)
        opp_error("UDPSocket: setOutputGate() must be invoked before socket can be used");

    check_and_cast<cSimpleModule *>(gateToUdp->getOwnerModule())->send(msg, gateToUdp);
}

void UDPSocket::setCallbackObject ( CallbackInterface cb,
void *  yourPtr = NULL 
)

Sets a callback object, to be used with processMessage(). This callback object may be your simple module itself (if it multiply inherits from CallbackInterface too, that is you declared it as

 class MyAppModule : public cSimpleModule, public UDPSocket::CallbackInterface
 

and redefined the necessary virtual functions; or you may use dedicated class (and objects) for this purpose.

UDPSocket doesn't delete the callback object in the destructor or on any other occasion.

YourPtr is an optional pointer. It may contain any value you wish -- UDPSocket will not look at it or do anything with it except passing it back to you in the CallbackInterface calls. You may find it useful if you maintain additional per-connection information: in that case you don't have to look it up by sockId in the callbacks, you can have it passed to you as yourPtr.

Definition at line 178 of file UDPSocket.cc.

{
    cb = callback;
    yourPtr = yourPointer;
}

void UDPSocket::setMulticastInterfaceId ( int  interfaceId  )  [inline]

Set the output interface for sending multicast packets (like the Unix IP_MULTICAST_IF socket option). The argument is the interface's Id in InterfaceTable.

Definition at line 221 of file UDPSocket.h.

{mcastIfaceId = interfaceId;}

void UDPSocket::setOutputGate ( cGate *  toUdp  )  [inline]

Sets the gate on which to send to UDP. Must be invoked before socket can be used. Example: socket.setOutputGate(gate("udpOut"));

Definition at line 196 of file UDPSocket.h.

Referenced by LDP::initialize().

{gateToUdp = toUdp;}

void UDPSocket::setUserId ( int  userId  ) 

Sets userId to an arbitrary value. (This value will be sent back to us by UDP in UDPControlInfo if we receive a packet on this socket.)

Definition at line 63 of file UDPSocket.cc.

{
    if (sockstate!=NOT_BOUND)
        opp_error("UDPSocket::setUserId(): cannot change userId after socket is bound");
    usrId = userId;
}

const char * UDPSocket::stateName ( int  state  )  [static]

Returns name of socket state code returned by getState().

Definition at line 37 of file UDPSocket.cc.

{
#define CASE(x) case x: s=#x; break
    const char *s = "unknown";
    switch (state)
    {
        CASE(NOT_BOUND);
        CASE(BOUND);
    }
    return s;
#undef CASE
}


Member Data Documentation

Definition at line 130 of file UDPSocket.h.

Referenced by processMessage(), setCallbackObject(), and UDPSocket().

cGate* UDPSocket::gateToUdp [protected]

Definition at line 133 of file UDPSocket.h.

Referenced by sendToUDP(), and UDPSocket().

Definition at line 124 of file UDPSocket.h.

Referenced by bind(), and sendTo().

int UDPSocket::localPrt [protected]

Definition at line 125 of file UDPSocket.h.

Referenced by bind(), sendTo(), and UDPSocket().

int UDPSocket::mcastIfaceId [protected]

Definition at line 128 of file UDPSocket.h.

Referenced by sendTo(), and UDPSocket().

Definition at line 126 of file UDPSocket.h.

Referenced by connect(), and send().

int UDPSocket::remotePrt [protected]

Definition at line 127 of file UDPSocket.h.

Referenced by connect(), send(), and UDPSocket().

int UDPSocket::sockId [protected]

Definition at line 120 of file UDPSocket.h.

Referenced by belongsToSocket(), bind(), close(), connect(), processMessage(), sendTo(), and UDPSocket().

int UDPSocket::sockstate [protected]

Definition at line 122 of file UDPSocket.h.

Referenced by bind(), close(), connect(), processMessage(), setUserId(), and UDPSocket().

int UDPSocket::usrId [protected]

Definition at line 121 of file UDPSocket.h.

Referenced by bind(), setUserId(), and UDPSocket().

void* UDPSocket::yourPtr [protected]

Definition at line 131 of file UDPSocket.h.

Referenced by processMessage(), setCallbackObject(), and UDPSocket().


The documentation for this class was generated from the following files: