Skip to content
Payton Turnage edited this page Dec 30, 2013 · 8 revisions

Creating a node

The basic entity in miknet is a miknode. You need a miknode to do anything. To create a miknode, declare a struct and initialize it to zero, then pass it to the constructor.

miknode_t node = {0};          /* declare struct; initialize to zero */

int err = miknode(&node,     /* pointer to the new node */
                  MIK_IPV6,  /* IP mode, MIK_IPV4 or MIK_IPV6 */
                  7000,      /* port to bind to (0 for auto-assign) */
                  20);       /* maximum amount of peers allowed to connect */

if (err < 0)
        /* handle errors */

That's it! Your node is ready to do things.

Connecting to another node

Connect to other nodes with the miknode_connect function. It will return the slot the new peer is in in the node's peer array, or -1 on failure.

int position = miknode_connect(&node,       /* pointer to the node */
                               "10.0.0.63", /* address to connect to */
                               2433);       /* port to connect on */

if (position < 0)
        /* handle errors */

Polling

In order to process incoming packets and execute queued commands, the node needs to be able to poll. Call miknode_poll() on a configured node to do this.

miknode_poll(&node,  /* pointer to the node */
             100);   /* time in milliseconds to poll */

After polling, you will have a linked list in node.packs of events that the node picked up during its poll.

Processing packets

This is simpler than english would make it sound; the following is a snippet from the test program included in the source distribution

...
/* Let the node execute queued commands and collect
   incoming packets. Provide it a ~maximum blocking
   time in milliseconds. */
miknode_poll(&node, 100);

/* After a call to miknode_poll, fetch events from mikevent
   until there are no more events to handle. Make sure to
   handle all events before polling again, or those events will
   be lost. */

mikpack_t *event = mikevent(&node);

while (event) {

        /* Event types
                MIK_JOIN: A new peer joined; data field is NULL.
                MIK_QUIT: A peer quit; data field is NULL.
                MIK_DATA: A peer sent data; data field is set. 
        */

        /* Miknet events can occur on many virtual channels,
           market by an unsigned 32 bit integer. The default
           channel (for join/quit notifications) is 0. */
        printf("Event on channel %u; ", event->channel);

        if (event->type == MIK_JOIN) {
                printf("New peer in slot %d.\n", event->peer);
        } else if (event->type == MIK_QUIT) {
                printf("Lost peer in slot %d.\n", event->peer);
        } else if (event->type == MIK_DATA) {
                printf("Data from peer: %s\n", event->data);

                if (!strncmp(event->data, "quit\0", 5))
                        quit = 1;
        }

        event = mikevent(&node);
}
...

Sending data

Sending requires a pointer to data, the size of the data, and virtual channel to send the data on. Join and quit messages are sent by default over the 0 channel, and the seperation is often useful, but you can use whatever channel you want.

miknode_send(&node.peers[index],  /* pointer to the recipient peer */
             "Hello!",            /* pointer to the data to send */
             7,                   /* length of the data */
             1);                  /* channel to deliver the packet on */

Please be aware that the data is not actually sent upon this call; it is placed in queue, and sent when miknode_poll is next called.

Handling peers

Peers have a field called 'data' which is a void pointer; have it point to your own peer data struct or whatever you need to keep track of them. For example, the above could have included

...
if (packet.type == MIK_JOIN) {
        printf("New peer in slot %d.\n", packet.peer);
        node.peers[packet.peer].data = "Peer's name.";
...

Closing up shop

Simple! Call miknode close

miknode_close(&node);

and it will take care of the sockets and memory held by the node.

Using only TCP

If you want to use miknet with programs that are not using miknet (e.g. use it as an easier way to control a "bare" TCP connection), switch the protocol of the peer. Below is the declaration of the function.

int mikpeer_switch_protocol (mikpeer_t *peer);

Pass it a pointer to the peer. This will toggle the peer between using the miknet protocol, and a bare TCP protocol.

In this mode you are responsible for identifying the separation of packets. When there is traffic on a peer's socket, miknet will read MIK_TCP_MAX bytes, so if there are two 7 byte packets, and MIK_TCP_MAX is 14 or greater, it will appear to be one 14 byte packet. You can adjust the read size to your needs using

void mik_set_readsize(uint32_t size);

By default, the read size is set to 1200.

Return to table of contents.

Clone this wiki locally