![]() |
||||||||
|
|
||||||||
Server and client are both implemented by deriving from ZCom_Control, so the client code will look very familiar.
class Client : public ZCom_Control { };
class Client : public ZCom_Control { void ZCom_cbConnectResult( ZCom_ConnID _id, eZCom_ConnectResult _result, ZCom_BitStream &_reply ) {} bool ZCom_cbConnectionRequest( ZCom_ConnID _id, ZCom_BitStream &_request, ZCom_BitStream &_reply ){return false;} void ZCom_cbConnectionSpawned( ZCom_ConnID _id ) {} void ZCom_cbConnectionClosed( ZCom_ConnID _id, eZCom_CloseReason _reason, ZCom_BitStream &_reasondata ) {} bool ZCom_cbZoidRequest( ZCom_ConnID _id, zU8 _requested_level, ZCom_BitStream &_reason ) {return false;} void ZCom_cbZoidResult( ZCom_ConnID _id, eZCom_ZoidResult _result, zU8 _new_level, ZCom_BitStream &_reason ) {} void ZCom_cbNodeRequest_Dynamic( ZCom_ConnID _id, ZCom_ClassID _requested_class, ZCom_BitStream *_announcedata, eZCom_NodeRole _role, ZCom_NodeID _net_id ) {} void ZCom_cbNodeRequest_Tag( ZCom_ConnID _id, ZCom_ClassID _requested_class, ZCom_BitStream *_announcedata, eZCom_NodeRole _role, zU32 _tag ) {} void ZCom_cbDataReceived( ZCom_ConnID _id, ZCom_BitStream &_data ) {} bool ZCom_cbDiscoverRequest( const ZCom_Address &_addr, ZCom_BitStream &_request, ZCom_BitStream &_reply ) {return false;} void ZCom_cbDiscovered( const ZCom_Address & _addr, ZCom_BitStream &_reply ) {} };
This is exactly the same as we did for the server in step 2. Now the relevant callbacks get implemented.
That leaves us with this set of callbacks:
Connecting to another ZCom_Control is asynchronous. That means, when you call ZCom_Connect() the connection process gets started but the method returns before the connection is established. The connection is established when ZCom_cbConnectResult() gets called with a positive result code. The net effect is that you can establish a connection to a remote host while the application can do other things in the meantime, like updating the GUI. Otherwise everything would freeze until the connection has been established.
class Client : public ZCom_Control { virtual void ZCom_cbConnectResult( ZCom_ConnID _id, eZCom_ConnectResult _result, ZCom_BitStream &_reply ) { if (_result == eZCom_ConnAccepted) printf("Connection established.\n"); else printf("Connection failed\n"); } // all other callback methods omitted here };
For a list of possible result codes see eZCom_ConnectResult. The _reply parameter contains anything the server has put there while executing ZCom_cbConnectionRequest().
class Client : public ZCom_Control { virtual void ZCom_cbConnectionClosed( ZCom_ConnID _id, eZCom_CloseReason _reason, ZCom_BitStream &_reasondata ) { printf("Connection to server closed"); } // all other callback methods omitted here };
// <- insert complete client class here int main() { // initialize Zoidcom ZoidCom* zcom = new ZoidCom("zoidcom.log"); if (!zcom || !zcom->Init()) exit(255); // make instance of our Client class Client *client = new Client(); // more soon return 0; };
// this creates and initializes the network sockets // true = use udp socket, 0 = let OS choose UDP port, 0 = no internal socket bool result = client->ZCom_initSockets(true, 0, 0); // if result is false, Zoidcom had problems while initializing if (!result) exit(255); };
Insert this after the socket initialization code:
ZCom_Address server_addr; server_addr.setAddress( eZCom_AddressUDP, 0, "localhost:10000"); ZCom_ConnID connection_id = client->ZCom_Connect(server_addr, NULL); // unable to connect // this happens if the connection process can't even be started // for some reason if (connection_id == ZCom_Invalid_ID) exit(255);
I suggest you store the connection ID somewhere for later use. You need it everytime you want to send data over that connection and for other things, too.
Note that it is possible to connect to as many other ZCom_Controls as you like in parallel. Each call to ZCom_Connect() returns a new connection ID, which can then be used to identify the connection in other callbacks.
After ZCom_Connect() has been called, it is necessary to wait for ZCom_cbConnectResult() to get called by Zoidcom.
while ( true ) { // tell the client to process incoming data client->ZCom_processInput(); // tell the client to process outgoing data client->ZCom_processOutput(); // give up remaining cpu time zcom->Sleep(1); }
#include <stdlib.h> #include <stdio.h> #include <zoidcom.h> bool exit_now = false; class Client : public ZCom_Control { void ZCom_cbConnectResult( ZCom_ConnID _id, eZCom_ConnectResult _result, ZCom_BitStream &_reply ) { if (_result == eZCom_ConnAccepted) printf("Connection established. \n"); else printf("Connection failed\n"); } void ZCom_cbConnectionClosed( ZCom_ConnID _id, eZCom_CloseReason _reason, ZCom_BitStream &_reasondata ) { printf("Connection to server closed. Exiting...\n"); exit_now = true; } bool ZCom_cbConnectionRequest( ZCom_ConnID _id, ZCom_BitStream &_request, ZCom_BitStream &_reply ){return false;} void ZCom_cbConnectionSpawned( ZCom_ConnID _id ) {} bool ZCom_cbZoidRequest( ZCom_ConnID _id, zU8 _requested_level, ZCom_BitStream &_reason ) {return false;} void ZCom_cbZoidResult( ZCom_ConnID _id, eZCom_ZoidResult _result, zU8 _new_level, ZCom_BitStream &_reason ) {} void ZCom_cbNodeRequest_Dynamic( ZCom_ConnID _id, ZCom_ClassID _requested_class, ZCom_BitStream *_announcedata, eZCom_NodeRole _role, ZCom_NodeID _net_id ) {} void ZCom_cbDataReceived( ZCom_ConnID _id, ZCom_BitStream &_data) {} void ZCom_cbNodeRequest_Tag( ZCom_ConnID _id, ZCom_ClassID _requested_class, ZCom_BitStream *_announcedata, eZCom_NodeRole _role, zU32 _tag ) {} bool ZCom_cbDiscoverRequest( const ZCom_Address &_addr, ZCom_BitStream &_request, ZCom_BitStream &_reply ) {return false;} void ZCom_cbDiscovered( const ZCom_Address & _addr, ZCom_BitStream &_reply ) {} }; int main() { // initialize Zoidcom ZoidCom* zcom = new ZoidCom("zoidcom.log"); if (!zcom || !zcom->Init()) exit(255); // make instance of our Client class Client *client = new Client(); client->ZCom_setDebugName("Client"); // this creates and initializes the network sockets // true = use udp socket, 0 = let OS choose UDP port, 0 = no internal socket bool result = client->ZCom_initSockets(true, 0, 0); // if result is false, Zoidcom had problems while initializing if (!result) exit(255); // put this into a codeblock so that server_addr gets out of scope before // 'delete zcom;' get called (everything needs to be gone before the // ZoidCom object gets deleted) { // prepare the destination adress ZCom_Address server_addr; server_addr.setAddress( eZCom_AddressUDP, 0, "localhost:10000"); // and connect ZCom_ConnID connection_id = client->ZCom_Connect(server_addr, NULL); // unable to connect // this happens if the connection process can't even be started // for some reason if (connection_id == ZCom_Invalid_ID) exit(255); } while ( !exit_now ) { // tell the client to process incoming data client->ZCom_processInput(); // tell the client to process outgoing data client->ZCom_processOutput(); // give up remaining cpu time zcom->Sleep(1); } delete client; delete zcom; return 0; };
1.4.6-NO