Simple Module TCPBasicClientApp

Package: inet.applications.tcpapp
File: src/inet/applications/tcpapp/TCPBasicClientApp.ned

C++ definition

Client for a generic request-response style protocol over TCP. May be used as a rough model of HTTP or FTP users. Compatible with both IPv4 (IPv4) and IPv6.

The model communicates with the server in sessions. During a session, the client opens a single TCP connection to the server, sends several requests (always waiting for the complete reply to arrive before sending a new request), and closes the connection.

The server app should be TCPGenericSrvApp; the model sends GenericAppMsg messages.

Example settings:

FTP:

   numRequestsPerSession = exponential(3)
   requestLength = truncnormal(20,5)
   replyLength = exponential(1000000)

Note that this module doesn't open separate TCP connections for commands and data transfer as the FTP protocol.

HTTP:

   numRequestsPerSession = 1 (HTTP 1.0)
   numRequestsPerSession = exponential(5) (HTTP 1.1, with keepalive)
   requestLength = truncnormal(350,20)
   replyLength = exponential(2000)

Note that since most web pages contain images and may contain frames, applets etc, possibly from various servers, and browsers usually download these items in parallel to the main HTML document, this module cannot serve as a realistic web client.

Also, with HTTP 1.0 it is the server that closes the connection after sending the response, while in this model it is the client.

Configuring App

The module parameter dataTransferMode should be set the transfer mode in TCP layer. Currently you have three choices:

  1. set them to "bytecount". This mode manages "virtual bytes", that is, only byte counts are transmitted over the TCP connection and no actual data. cMessage contents, and even message boundaries are not preserved with these classes: for example, if the client sends a single cMessage with length = 1 megabyte over TCP, the receiver-side client will see a sequence of MSS-sized messages.
  2. use "object", which transmits cMessage objects (and subclasses) over a TCP connection. The same message object sequence that was sent by the client to the sender-side TCP entity will be reproduced on the receiver side. If a client sends a cMessage with length = 1 megabyte, the receiver-side client will receive the same message object (or a clone) after the TCP entities have completed simulating the transmission of 1 megabyte over the connection. This is a different behaviour from TCPVirtualDataSendQueue/RcvQueue. This mode is not implemented in TCP_NSC yet.
  3. use "bytestream", which transmits real bytes of messages.

See also: TCPGenericSrvApp, GenericAppMsg, TelnetApp

TCPBasicClientApp

Usage diagram:

The following diagram shows usage relationships between types. Unresolved types are missing from the diagram.

Inheritance diagram:

The following diagram shows inheritance relationships for this type. Unresolved types are missing from the diagram.

Parameters:

Name Type Default value Description
localAddress string ""

may be left empty ("")

localPort int -1

port number to listen on

connectAddress string ""

server address (may be symbolic)

connectPort int 1000

port number to connect to

dataTransferMode string "bytecount"
startTime double 1s

time first session begins

stopTime double -1s

time of finishing sending, negative values mean forever

numRequestsPerSession int 1

number of requests sent per session

requestLength int 200B

length of a request

replyLength int 1MiB

length of a reply

thinkTime double

time gap between requests

idleInterval double

time gap between sessions

reconnectInterval double 30s

if connection breaks, waits this much before trying to reconnect

Properties:

Name Value Description
display i=block/app

Gates:

Name Direction Size Description
tcpIn input
tcpOut output

Signals:

Name Type Unit
sentPk cPacket
rcvdPk cPacket
connect long

Statistics:

Name Title Source Record Unit Interpolation Mode
numSessions total number of sessions sum(connect+1)/2 last
sentPk packets sent sentPk count, sum(packetBytes), vector(packetBytes) none
rcvdPk packets received rcvdPk count, sum(packetBytes), vector(packetBytes) none
numActiveSessions number of active sessions sum(connect) max, timeavg, vector sample-hold
endToEndDelay end-to-end delay messageAge(rcvdPk) histogram, vector s none

Source code:

//
// Client for a generic request-response style protocol over TCP.
// May be used as a rough model of HTTP or FTP users.
// Compatible with both IPv4 (~IPv4) and ~IPv6.
//
// The model communicates with the server in sessions. During a session,
// the client opens a single TCP connection to the server, sends several
// requests (always waiting for the complete reply to arrive before
// sending a new request), and closes the connection.
//
// The server app should be ~TCPGenericSrvApp; the model sends ~GenericAppMsg
// messages.
//
// Example settings:
//
// FTP:
// <pre>
//    numRequestsPerSession = exponential(3)
//    requestLength = truncnormal(20,5)
//    replyLength = exponential(1000000)
// </pre>
//
// Note that this module doesn't open separate TCP connections for commands
// and data transfer as the FTP protocol.
//
// HTTP:
// <pre>
//    numRequestsPerSession = 1 <i>(HTTP 1.0)</i>
//    numRequestsPerSession = exponential(5) <i>(HTTP 1.1, with keepalive)</i>
//    requestLength = truncnormal(350,20)
//    replyLength = exponential(2000)
// </pre>
//
// Note that since most web pages contain images and may contain frames,
// applets etc, possibly from various servers, and browsers usually download
// these items in parallel to the main HTML document, this module cannot
// serve as a realistic web client.
//
// Also, with HTTP 1.0 it is the server that closes the connection after
// sending the response, while in this model it is the client.
//
// <b>Configuring App</b>
//
// The module parameter dataTransferMode should be set the transfer mode in TCP layer.
// Currently you have three choices:
//
//   -# set them to "bytecount".
//      This mode manages "virtual bytes", that is, only byte counts are
//      transmitted over the TCP connection and no actual data. cMessage
//      contents, and even message boundaries are not preserved with these
//      classes: for example, if the client sends a single cMessage with
//      length = 1 megabyte over TCP, the receiver-side client will see a
//      sequence of MSS-sized messages.
//
//   -# use "object", which transmits
//      cMessage objects (and subclasses) over a TCP connection. The same
//      message object sequence that was sent by the client to the
//      sender-side TCP entity will be reproduced on the receiver side.
//      If a client sends a cMessage with length = 1 megabyte, the
//      receiver-side client will receive the same message object (or a clone)
//      after the TCP entities have completed simulating the transmission
//      of 1 megabyte over the connection. This is a different behaviour
//      from TCPVirtualDataSendQueue/RcvQueue.
//      This mode is not implemented in ~TCP_NSC yet.
//
//   -# use "bytestream", which transmits real bytes of messages.
//
// @see ~TCPGenericSrvApp, ~GenericAppMsg, ~TelnetApp
//
simple TCPBasicClientApp like ITCPApp
{
    parameters:
        string localAddress = default(""); // may be left empty ("")
        int localPort = default(-1); // port number to listen on
        string connectAddress = default("");  // server address (may be symbolic)
        int connectPort = default(1000); // port number to connect to
        string dataTransferMode @enum("bytecount","object","bytestream") = default("bytecount");
        double startTime @unit(s) = default(1s); // time first session begins
        double stopTime @unit(s) = default(-1s);  // time of finishing sending, negative values mean forever
        volatile int numRequestsPerSession = default(1);  // number of requests sent per session
        volatile int requestLength @unit(B) = default(200B); // length of a request
        volatile int replyLength @unit(B) = default(1MiB); // length of a reply
        volatile double thinkTime @unit(s); // time gap between requests
        volatile double idleInterval @unit(s); // time gap between sessions
        volatile double reconnectInterval @unit(s) = default(30s);  // if connection breaks, waits this much before trying to reconnect
        @display("i=block/app");
        @signal[sentPk](type=cPacket);
        @signal[rcvdPk](type=cPacket);
        @signal[connect](type=long);  // 1 for open, -1 for close
        @statistic[rcvdPk](title="packets received"; source=rcvdPk; record=count,"sum(packetBytes)","vector(packetBytes)"; interpolationmode=none);
        @statistic[sentPk](title="packets sent"; source=sentPk; record=count,"sum(packetBytes)","vector(packetBytes)"; interpolationmode=none);
        @statistic[endToEndDelay](title="end-to-end delay"; source="messageAge(rcvdPk)"; unit=s; record=histogram,vector; interpolationmode=none);
        @statistic[numActiveSessions](title="number of active sessions"; source="sum(connect)"; record=max,timeavg,vector; interpolationmode=sample-hold);
        @statistic[numSessions](title="total number of sessions"; source="sum(connect+1)/2"; record=last);
    gates:
        input tcpIn @labels(TCPCommand/up);
        output tcpOut @labels(TCPCommand/down);
}