NetworkEngine, TCP/IP Networking



connectToHost
enableTCPListen
disableTCPListen
getMaxConnections
getData
sendData
isConnected
getRemotePort
getRemoteIP
isNewClient
getUnsentBytes
disconnectThread
getErrMsg

The NetworkEngine class is responsible for DyConnect's TCP/IP networking. A NetworkEngine can manage multiple TCP/IP connections by assigning each one to a separate thread. The threads handle the sending and receiving of data, and can be accessed and controlled with the following functions. Each connection is referred to by it's thread index:

NetworkEngine netEngine;
DyBytes theData;

if (netEngine.isConnected(2))
getData(2, theData);

This code checks if there is a client connected on thread 2. If yes, it retrieves any data the client has sent, and appends it to theData.

A note on starvation: Each connection continually runs in a separate thread. To make them run smoothly, it's a good idea to call your favourite sleep function multiple times per second. Whenever the computer sees a 'sleep' command, it will schedule other threads to run. This lets the NetworkEngine get regular access to the CPU, and helps reduce lag. For example:

while (theData.size() == 0){
netEngine.getData(2, theData);
DyConnect::dySleep(20); //sleep for 20 milliseconds
}

The duration of the sleep can be as brief as you like.


int connectToHost(string ipAddress, int portNumber);

Connect to the host at the specified address and port number. Returns the index of the thread that is handling the connection, or negative if we couldn't connect. Note that this is a blocking function. Execution will pause here until we successfully connect or give up trying. See PollingConnect for a non-blocking version.

This function sets errMsg on failure.


bool enableTCPListen(int portNumber);

Tell the NetworkEngine to listen for incoming TCP/IP connections on the specified port number. It returns false if it encounters errors, and stores a description of the problem in errMsg.

When a new client connects, it will automatically be assigned to an idle thread. You can check for new connections using isNewClient. The client is disconnected if there's no thread available. Each NetworkEngine will only listen on one port at a time. If you need to listen for connections on multiple ports, you need to create multiple NetworkEngine instances.


void disableTCPListen(void);

Stop listening for incoming TCP/IP connections.


int getMaxConnections(void);

Returns the maximum number of connections that can be handled at once. See setMaxConnections. To check each thread's status, you would use something like this:

for (int i = 0; i < netEngine.getMaxConnections(); i++){
if (netEngine.isConnected(i))
cout << "There's a client connected on thread " << i << endl;
}

void getData(int threadPos, DyBytes *theData);
void getData(int threadPos, DyBytes &theData);

Receive data from the specified client, and append it to theData.

When a thread disconnects, its receive buffer is cleared. You're given a two second delay after a disconnect to call getData() before this happens.


void sendData(int threadPos, DyBytes *theData);
void sendData(int threadPos, DyBytes &theData);

Send theData to the specified client.

When a thread disconnects, its send buffer is cleared two seconds later. This delay is meant to prevent you from accidentally sending the original client's data to a new client that might have connected on the same thread.

Note that you can call sendData() on disconnected threads. There are two possible outcomes: 1) You sent the data immediately after the thread disconnected. In this case, the data is simply erased. 2) You sent the data two or more seconds after a disconnect, or there has never been a connection on this thread. In this case, the data remains in memory. It is sent to the first client to connect on this thread.


bool isConnected(int threadPos);

Returns true if there is a client connected on the specified thread.


string getRemoteAddr(int threadPos);

Returns the IP address of the client connected on the specified thread. Returns "0.0.0.0" if that thread isn't connected.


int getRemotePort(int threadPos);

Returns the port number of the client connected on the specified thread. Returns 0 if that thread isn't connected.


bool isNewClient(int threadPos);

Returns true if there's a new client on the specified thread. Subsequent calls to isNewClient will return false until a new client connects.


long int getUnsentBytes(int threadPos);

Returns the number of bytes the specified thread still has to send. If you sent a large amount of data, you can use this to keep track of how much has been sent so far.

This function is also useful for reducing lag. If getUnsentBytes() returns a large number, you might want to wait a bit before sending more data.


void disconnectThread(int threadPos);

Disconnect the client at the specified thread position.


string getErrMsg(void);

Returns a description of the most recent error for this NetworkEngine.