|
INET Framework for OMNeT++/OMNEST
|
TcpSocket is a convenience class, to make it easier to manage TCP connections from your application models. More...
#include <TcpSocket.h>
Classes | |
| class | ICallback |
| Callback interface for TCP sockets, see setCallback() and processMessage() for more info. More... | |
| class | ReceiveQueueBasedCallback |
Public Types | |
| enum | State { NOT_BOUND, BOUND, LISTENING, CONNECTING, CONNECTED, PEER_CLOSED, LOCALLY_CLOSED, CLOSED, SOCKERROR } |
Public Member Functions | |
| TcpSocket () | |
| Constructor. More... | |
| TcpSocket (cMessage *msg) | |
| Constructor, to be used with forked sockets (see listen()). More... | |
| TcpSocket (TcpAvailableInfo *availableInfo) | |
| Constructor, to be used with forked sockets (see listen()). More... | |
| ~TcpSocket () | |
| Destructor. More... | |
| int | getSocketId () const override |
| Returns the internal connection Id. More... | |
| ChunkQueue * | getReceiveQueue () |
| void * | getUserData () const |
| void | setUserData (void *userData) |
| TcpSocket::State | getState () const |
| Returns the socket state, one of NOT_BOUND, CLOSED, LISTENING, CONNECTING, CONNECTED, etc. More... | |
| void | setState (TcpSocket::State state) |
Getter functions | |
| L3Address | getLocalAddress () const |
| int | getLocalPort () const |
| L3Address | getRemoteAddress () const |
| int | getRemotePort () const |
Opening and closing connections, sending data | |
| void | setOutputGate (cGate *toTcp) |
| Sets the gate on which to send to TCP. More... | |
| void | bind (int localPort) |
| Bind the socket to a local port number. More... | |
| void | bind (L3Address localAddr, int localPort) |
| Bind the socket to a local port number and IP address (useful with multi-homing). More... | |
| const char * | getTCPAlgorithmClass () const |
| Returns the current tcpAlgorithmClass parameter. More... | |
| void | setTCPAlgorithmClass (const char *tcpAlgorithmClass) |
| Sets the tcpAlgorithmClass parameter of the next connect() or listen() call. More... | |
| void | listen () |
| Initiates passive OPEN, creating a "forking" connection that will listen on the port you bound the socket to. More... | |
| void | listenOnce () |
| Initiates passive OPEN to create a non-forking listening connection. More... | |
| void | accept (int socketId) |
| Accepts a new incoming connection reported as available. More... | |
| void | connect (L3Address remoteAddr, int remotePort) |
| Active OPEN to the given remote socket. More... | |
| virtual void | send (Packet *msg) override |
| Sends data packet. More... | |
| void | sendCommand (Request *msg) |
| Sends command. More... | |
| void | close () override |
| Closes the local end of the connection. More... | |
| void | abort () |
| Aborts the connection. More... | |
| virtual void | destroy () override |
| Destroy the connection. More... | |
| void | requestStatus () |
| Causes TCP to reply with a fresh TcpStatusInfo, attached to a dummy message as getControlInfo(). More... | |
| void | setTimeToLive (int ttl) |
| Set the TTL (Ipv6: Hop Limit) field on sent packets. More... | |
| void | setDscp (short dscp) |
| Sets the Ipv4 / Ipv6 dscp fields of packets sent from the TCP socket. More... | |
| void | setTos (short tos) |
| Sets the Ipv4 Type of Service / Ipv6 Traffic Class fields of packets sent from the TCP socket. More... | |
| void | renewSocket () |
| Required to re-connect with a "used" TcpSocket object. More... | |
| virtual bool | isOpen () const override |
Handling of messages arriving from TCP | |
| virtual bool | belongsToSocket (cMessage *msg) const override |
| Returns true if the message belongs to this socket instance (message has a TcpCommand as getControlInfo(), and the connId in it matches that of the socket.) More... | |
| void | setCallback (ICallback *cb) |
| Sets a callback object, to be used with processMessage(). More... | |
| void | processMessage (cMessage *msg) override |
| Examines the message (which should have arrived from TCP), updates socket state, and if there is a callback object installed (see setCallback(), class ICallback), dispatches to the appropriate method. More... | |
Public Member Functions inherited from inet::ISocket | |
| virtual | ~ISocket () |
Static Public Member Functions | |
| static const char * | stateName (TcpSocket::State state) |
| Returns name of socket state code returned by getState(). More... | |
Protected Member Functions | |
| void | sendToTcp (cMessage *msg, int c=-1) |
| void | listen (bool fork) |
Protected Attributes | |
| int | connId = -1 |
| State | sockstate = NOT_BOUND |
| L3Address | localAddr |
| int | localPrt = -1 |
| L3Address | remoteAddr |
| int | remotePrt = -1 |
| ICallback * | cb = nullptr |
| void * | userData = nullptr |
| cGate * | gateToTcp = nullptr |
| std::string | tcpAlgorithmClass |
| ChunkQueue * | receiveQueue = nullptr |
TcpSocket is a convenience class, to make it easier to manage TCP connections from your application models.
You'd have one (or more) TcpSocket 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.
TcpSocket chooses and remembers the connId 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()):
TcpSocket socket; socket.connect(Address("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 TcpSocket do part of the job. For the latter, you give TcpSocket a callback object on which it'll invoke the appropriate member functions: socketEstablished(), socketDataArrived(), socketFailure(), socketPeerClosed(), etc (these are methods of TcpSocket::ICallback)., The callback object can be your simple module class too.
This code skeleton example shows how to set up a TcpSocket to use the module itself as callback object:
class MyModule : public cSimpleModule, public TcpSocket::ICallback { TcpSocket socket; virtual void socketDataArrived(TcpSocket *tcpSocket, cPacket *msg, bool urgent); virtual void socketFailure(int connId, int code); ... };
void MyModule::initialize() {
socket.setCallback(this);
}void MyModule::handleMessage(cMessage *msg) {
if (socket.belongsToSocket(msg))
socket.processMessage(msg); // dispatch to socketTODOX() methods
else
...
}void MyModule::socketDataArrived(TcpSocket *tcpSocket, cPacket *msg, bool) {
EV << "Received TCP data, " << msg->getByteLength() << " bytes\\n";
delete msg;
}void MyModule::socketFailure(TcpSocket *tcpSocket, int code) {
if (code==TCP_I_CONNECTION_RESET)
EV << "Connection reset!\\n";
else if (code==TCP_I_CONNECTION_REFUSED)
EV << "Connection refused!\\n";
else if (code==TCP_I_TIMEOUT)
EV << "Connection timed out!\\n";
}
If you need to manage a large number of sockets (e.g. in a server application which handles multiple incoming connections), the SocketMap class may be useful. The following code fragment to handle incoming connections is from the Ldp module:
TcpSocket *socket = check_and_cast_nullable<TcpSocket*>socketMap.findSocketFor(msg); if (!socket) { // not yet in socketMap, must be new incoming connection: add to socketMap socket = new TcpSocket(msg); socket->setOutputGate(gate("tcpOut")); socket->setCallback(this); socketMap.addSocket(socket); } // dispatch to socketEstablished(), socketDataArrived(), socketPeerClosed() // or socketFailure() socket->processMessage(msg);
| Enumerator | |
|---|---|
| NOT_BOUND | |
| BOUND | |
| LISTENING | |
| CONNECTING | |
| CONNECTED | |
| PEER_CLOSED | |
| LOCALLY_CLOSED | |
| CLOSED | |
| SOCKERROR | |
| inet::TcpSocket::TcpSocket | ( | ) |
Constructor.
The getConnectionId() method returns a valid Id right after constructor call.
| inet::TcpSocket::TcpSocket | ( | cMessage * | msg | ) |
Constructor, to be used with forked sockets (see listen()).
The new connId will be picked up from the message: it should have arrived from TCP and contain TCPCommmand control info.
| inet::TcpSocket::TcpSocket | ( | TcpAvailableInfo * | availableInfo | ) |
Constructor, to be used with forked sockets (see listen()).
| inet::TcpSocket::~TcpSocket | ( | ) |
Destructor.
| void inet::TcpSocket::abort | ( | ) |
Aborts the connection.
Referenced by inet::bgp::BgpRouter::openTCPConnectionToPeer(), and inet::NetPerfMeter::teardownConnection().
| void inet::TcpSocket::accept | ( | int | socketId | ) |
Accepts a new incoming connection reported as available.
Referenced by inet::TcpServerSocketIo::acceptSocket(), processMessage(), inet::TcpServerHostApp::socketAvailable(), inet::TcpAppBase::socketAvailable(), inet::TcpServerThreadBase::socketAvailable(), inet::bgp::BgpRouter::socketAvailable(), and inet::Ldp::socketAvailable().
|
overridevirtual |
Returns true if the message belongs to this socket instance (message has a TcpCommand as getControlInfo(), and the connId in it matches that of the socket.)
Implements inet::ISocket.
Referenced by inet::TcpClientSocketIo::handleMessage(), inet::TcpServerSocketIo::handleMessage(), inet::TcpServerListener::handleMessageWhenUp(), inet::TcpServerHostApp::handleMessageWhenUp(), inet::Ldp::handleMessageWhenUp(), and processMessage().
| void inet::TcpSocket::bind | ( | int | localPort | ) |
Bind the socket to a local port number.
Referenced by inet::TcpAppBase::connect(), inet::NetPerfMeter::createAndBindSocket(), inet::TcpServerListener::handleStartOperation(), inet::TcpServerHostApp::handleStartOperation(), inet::TcpAppBase::initialize(), inet::TcpGenericServerApp::initialize(), inet::Ldp::initialize(), inet::TcpClientSocketIo::open(), inet::bgp::BgpRouter::openTCPConnectionToPeer(), and inet::Ldp::openTCPConnectionToPeer().
| void inet::TcpSocket::bind | ( | L3Address | localAddr, |
| int | localPort | ||
| ) |
Bind the socket to a local port number and IP address (useful with multi-homing).
|
overridevirtual |
Closes the local end of the connection.
With TCP, a CLOSE operation means "I have no more data to send", and thus results in a one-way connection until the remote TCP closes too (or the FIN_WAIT_1 timeout expires)
Implements inet::ISocket.
Referenced by inet::TcpAppBase::close(), inet::TcpGenericServerThread::dataArrived(), inet::TcpServerListener::handleStopOperation(), inet::TcpServerHostApp::handleStopOperation(), inet::Ldp::handleStopOperation(), inet::NetPerfMeter::handleTimer(), inet::bgp::BgpRouter::processMessageFromTCP(), and inet::Ldp::socketAvailable().
| void inet::TcpSocket::connect | ( | L3Address | remoteAddr, |
| int | remotePort | ||
| ) |
Active OPEN to the given remote socket.
Referenced by inet::TcpAppBase::connect(), inet::NetPerfMeter::establishConnection(), inet::TcpClientSocketIo::open(), inet::bgp::BgpRouter::openTCPConnectionToPeer(), and inet::Ldp::openTCPConnectionToPeer().
|
overridevirtual |
Destroy the connection.
Implements inet::ISocket.
Referenced by inet::TcpServerListener::handleCrashOperation(), inet::TelnetApp::handleCrashOperation(), inet::TcpBasicClientApp::handleCrashOperation(), inet::TcpSessionApp::handleCrashOperation(), inet::TcpServerHostApp::handleCrashOperation(), and inet::Ldp::handleCrashOperation().
|
inline |
Referenced by inet::operator<<(), and inet::bgp::BgpSession::sendOpenMessage().
|
inline |
Referenced by inet::operator<<().
|
inline |
|
inline |
Referenced by inet::operator<<(), inet::bgp::BgpRouter::processMessageFromTCP(), and inet::Ldp::socketAvailable().
|
inline |
Referenced by inet::operator<<().
|
inlineoverridevirtual |
Returns the internal connection Id.
TCP uses the (gate index, connId) pair to identify the connection when it receives a command from the application (or TcpSocket).
Implements inet::ISocket.
Referenced by inet::bgp::BgpRouter::findIdFromSocketConnId(), inet::operator<<(), inet::TcpServerHostApp::socketAvailable(), inet::bgp::BgpRouter::socketDataArrived(), inet::bgp::BgpRouter::socketEstablished(), inet::bgp::BgpRouter::socketFailure(), and TcpSocket().
|
inline |
Returns the socket state, one of NOT_BOUND, CLOSED, LISTENING, CONNECTING, CONNECTED, etc.
Messages received from TCP must be routed through processMessage() in order to keep socket state up-to-date.
Referenced by inet::TcpEchoAppThread::dataArrived(), inet::TcpBasicClientApp::handleStopOperation(), inet::bgp::BgpRouter::openTCPConnectionToPeer(), inet::operator<<(), inet::TcpAppBase::refreshDisplay(), inet::TcpSinkAppThread::refreshDisplay(), inet::TcpSessionApp::refreshDisplay(), inet::TcpServerThreadBase::refreshDisplay(), inet::TcpBasicClientApp::socketDataArrived(), and inet::TcpAppBase::socketPeerClosed().
|
inline |
Returns the current tcpAlgorithmClass parameter.
|
inline |
|
overridevirtual |
Implements inet::ISocket.
Referenced by inet::Ldp::handleMessageWhenUp(), inet::TelnetApp::handleStopOperation(), inet::TcpSessionApp::handleStopOperation(), inet::TelnetApp::socketClosed(), inet::TcpServerListener::socketClosed(), inet::TcpServerHostApp::socketClosed(), and inet::TcpSessionApp::socketClosed().
|
inline |
Initiates passive OPEN, creating a "forking" connection that will listen on the port you bound the socket to.
Every incoming connection will get a new connId (and thus, must be handled with a new TcpSocket object), while the original connection (original connId) will keep listening on the port. The new TcpSocket object must be created with the TcpSocket(cMessage *msg) constructor.
If you need to handle multiple incoming connections, the TcpSocketMap class can also be useful, and TcpServerHostApp shows how to put it all together. See also TcpOpenCommand documentation (neddoc) for more info.
Referenced by listen().
|
protected |
|
inline |
Initiates passive OPEN to create a non-forking listening connection.
Non-forking means that TCP will accept the first incoming connection, and refuse subsequent ones.
See TcpOpenCommand documentation (neddoc) for more info.
|
overridevirtual |
Examines the message (which should have arrived from TCP), updates socket state, and if there is a callback object installed (see setCallback(), class ICallback), dispatches to the appropriate method.
The method deletes the message, unless (1) there is a callback object installed AND (2) the message is payload (message kind TCP_I_DATA or TCP_I_URGENT_DATA) when the responsibility of destruction is on the socketDataArrived() callback method.
IMPORTANT: for performance reasons, this method doesn't check that the message belongs to this socket, i.e. belongsToSocket(msg) would return true!
Implements inet::ISocket.
Referenced by inet::TcpClientSocketIo::handleMessage(), inet::TcpServerSocketIo::handleMessage(), inet::TcpGenericServerApp::handleMessage(), inet::TcpServerListener::handleMessageWhenUp(), inet::TcpServerHostApp::handleMessageWhenUp(), inet::TcpAppBase::handleMessageWhenUp(), inet::Ldp::handleMessageWhenUp(), and inet::bgp::BgpRouter::processMessageFromTCP().
| void inet::TcpSocket::renewSocket | ( | ) |
Required to re-connect with a "used" TcpSocket object.
By default, a TcpSocket object is tied to a single TCP connection, via the connectionId. When the connection gets closed or aborted, you cannot use the socket to connect again (by connect() or listen()) unless you obtain a new connectionId by calling this method.
BEWARE if you use TcpSocketMap! TcpSocketMap uses connectionId to find TCPSockets, so after calling this method you have to remove the socket from your TcpSocketMap, and re-add it. Otherwise TcpSocketMap will get confused.
The reason why one must obtain a new connectionId is that TCP still has to maintain the connection data structure (identified by the old connectionId) internally for a while (2 maximum segment lifetimes = 240s) after it reported "connection closed" to us.
Referenced by inet::TcpAppBase::connect(), inet::NetPerfMeter::establishConnection(), and inet::bgp::BgpRouter::openTCPConnectionToPeer().
| void inet::TcpSocket::requestStatus | ( | ) |
Causes TCP to reply with a fresh TcpStatusInfo, attached to a dummy message as getControlInfo().
The reply message can be recognized by its message kind TCP_I_STATUS, or (if a callback object is used) the socketStatusArrived() method of the callback object will be called.
|
overridevirtual |
Sends data packet.
Implements inet::ISocket.
Referenced by inet::TcpGenericServerThread::dataArrived(), inet::TcpClientSocketIo::handleMessage(), inet::TcpServerSocketIo::handleMessage(), inet::bgp::BgpSession::sendKeepAliveMessage(), inet::bgp::BgpSession::sendOpenMessage(), inet::TcpAppBase::sendPacket(), inet::Ldp::sendToPeer(), inet::bgp::BgpSession::sendUpdateMessage(), and inet::NetPerfMeter::transmitFrame().
| void inet::TcpSocket::sendCommand | ( | Request * | msg | ) |
Sends command.
Referenced by inet::NetPerfMeter::sendTCPQueueRequest().
|
protected |
Referenced by abort(), accept(), close(), connect(), destroy(), listen(), requestStatus(), send(), sendCommand(), setDscp(), setTimeToLive(), and setTos().
| void inet::TcpSocket::setCallback | ( | ICallback * | cb | ) |
Sets a callback object, to be used with processMessage().
This callback object may be your simple module itself (if it multiply inherits from ICallback too, that is you declared it as
class MyAppModule : public cSimpleModule, public TcpSocket::ICallback
and redefined the necessary virtual functions; or you may use dedicated class (and objects) for this purpose.
TcpSocket doesn't delete the callback object in the destructor or on any other occasion.
Referenced by inet::TcpServerSocketIo::acceptSocket(), inet::TcpServerListener::handleStartOperation(), inet::TcpServerHostApp::handleStartOperation(), inet::TcpAppBase::initialize(), inet::TcpClientSocketIo::open(), inet::bgp::BgpRouter::openTCPConnectionToPeer(), inet::Ldp::openTCPConnectionToPeer(), inet::bgp::BgpRouter::processMessageFromTCP(), inet::TcpServerHostApp::socketAvailable(), and inet::Ldp::socketAvailable().
| void inet::TcpSocket::setDscp | ( | short | dscp | ) |
Sets the Ipv4 / Ipv6 dscp fields of packets sent from the TCP socket.
Referenced by inet::TcpAppBase::connect().
|
inline |
Sets the gate on which to send to TCP.
Must be invoked before socket can be used. Example: socket.setOutputGate(gate("tcpOut"));
Referenced by inet::TcpServerSocketIo::acceptSocket(), inet::NetPerfMeter::createAndBindSocket(), inet::TcpServerListener::handleStartOperation(), inet::TcpServerHostApp::handleStartOperation(), inet::TcpAppBase::initialize(), inet::TcpGenericServerApp::initialize(), inet::Ldp::initialize(), inet::TcpClientSocketIo::open(), inet::bgp::BgpRouter::openTCPConnectionToPeer(), inet::Ldp::openTCPConnectionToPeer(), inet::bgp::BgpRouter::processMessageFromTCP(), inet::TcpServerHostApp::socketAvailable(), inet::Ldp::socketAvailable(), and inet::NetPerfMeter::successfullyEstablishedConnection().
|
inline |
|
inline |
| void inet::TcpSocket::setTimeToLive | ( | int | ttl | ) |
Set the TTL (Ipv6: Hop Limit) field on sent packets.
Referenced by inet::TcpAppBase::connect(), and inet::bgp::BgpRouter::openTCPConnectionToPeer().
| void inet::TcpSocket::setTos | ( | short | tos | ) |
Sets the Ipv4 Type of Service / Ipv6 Traffic Class fields of packets sent from the TCP socket.
Referenced by inet::TcpAppBase::connect().
|
inline |
|
static |
Returns name of socket state code returned by getState().
Referenced by inet::operator<<(), inet::TcpAppBase::refreshDisplay(), inet::TcpSinkAppThread::refreshDisplay(), inet::TcpSessionApp::refreshDisplay(), inet::TcpServerThreadBase::refreshDisplay(), and send().
|
protected |
Referenced by processMessage(), setCallback(), and ~TcpSocket().
|
protected |
Referenced by belongsToSocket(), renewSocket(), sendToTcp(), and TcpSocket().
|
protected |
Referenced by sendToTcp().
|
protected |
Referenced by bind(), connect(), listen(), processMessage(), renewSocket(), and TcpSocket().
|
protected |
Referenced by bind(), connect(), listen(), processMessage(), renewSocket(), and TcpSocket().
|
protected |
Referenced by ~TcpSocket().
|
protected |
Referenced by connect(), processMessage(), renewSocket(), and TcpSocket().
|
protected |
Referenced by connect(), processMessage(), renewSocket(), and TcpSocket().
Referenced by abort(), bind(), close(), connect(), destroy(), isOpen(), listen(), processMessage(), renewSocket(), send(), and TcpSocket().
|
protected |