Juan,
Ok, I spent 10 minutes doing a working example:
Common File
#include <errno.h>
#include <time.h>
#include <string>
#include <sys/neutrino.h>
#include <sys/netmgr.h>
#include <sys/dispatch.h>
struct Message
{
// This structure contains timer events
struct _pulse timerPulse;
// This is user event message data
char data[100];
};
Server Code:
#include "test.h"
using namespace std;
int main()
{
name_attach_t *nameAttach; // QNX global name struct
int channelId;
int connectId;
int processId = 0; // Ourselves
if ((nameAttach = name_attach(NULL, "Foo", NAME_FLAG_ATTACH_GLOBAL)) == NULL)
{
printf( "Error!");
exit (-1);
}
channelId = nameAttach->chid;
// Connect to the channel to be able to receive messages
if ((connectId = ConnectAttach_r(ND_LOCAL_NODE, processId, channelId, _NTO_SIDE_CHANNEL, 0)) < 0)
{
printf("Connection failed on channel %d due to %s", channelId, strerror(abs(connectId)));
exit(-1);
}
// Receive a message or timer pulse
int recvId;
Message msg; // Incoming message or timerpulse
Message replyMsg;
while (1)
{
if ((recvId = MsgReceive_r(channelId, &msg, sizeof(Message), NULL)) < 0)
{
printf("Error %s while trying to receive a message over connection %d on channel %d", strerror(abs(recvId)), connectId, channelId);
exit(-1);
}
else
{
// Determine if we received a message or timer pulse
if (recvId == 0)
{
switch (msg.timerPulse.code)
{
case _PULSE_CODE_DISCONNECT:
// Remote side disconnecting via name_close() from a
// name_open (this only occurs for a server process
ConnectDetach_r(msg.timerPulse.scoid);
break;
case _PULSE_CODE_UNBLOCK:
// Sender hit by a signal so release them to process it
Message emptyReply;
int ret;
if ((ret = MsgReply_r(recvId, 0, &emptyReply, sizeof(Message))) < 0)
{
printf("Error %s while trying to reply to sender over connection %d on channel %d", strerror(abs(ret)), connectId, channelId);
}
break;
case _PULSE_CODE_THREADDEATH:
case _PULSE_CODE_COIDDEATH:
// Remote side died/exited!
break;
default:
// Timer pulse received. Do timer processing...
break;
}
}
else
{
// Reply to a name_open() call for servers
if (msg.timerPulse.type == _IO_CONNECT)
{
MsgReply_r(recvId, EOK, NULL, 0);
printf("Remote side %d connected to server\n", recvId);
}
else
{
// Process the message...
printf ("Received a message of %s\n", msg.data);
// Reply to unblock the other side.
sprintf(replyMsg.data,"Bar");
MsgReply_r(recvId, 0, &replyMsg, sizeof(Message));
}
}
}
}
}
Client Code
#include "test.h"
using namespace std;
int main()
{
int connectId; // Connect Id returned by QNX O/S
if ((connectId = name_open("Foo", NAME_FLAG_ATTACH_GLOBAL)) < 0)
{
printf("Error!");
exit(-1);
}
// Sends a message to the server
int ret;
Message msg; // Our data to the server
Message replyMsg; // Any reply data from the server
sprintf(msg.data,"Foo");
if ((ret = MsgSend_r(connectId, &msg, sizeof(Message), &replyMsg, sizeof(Message))) < 0)
{
printf("Error %s %d while trying to send message over connection %d", strerror(abs(ret)), ret, connectId);
exit(-1);
}
printf ("Server replied with %s\n", replyMsg.data);
}
On the server node (172.27.12.103), I started qnet via:
mount -Tio-net npm-qnet.so
I verified qnet started by doing ‘ls /net’ and I saw my hostname there.
I started gns in server mode via:
gns -s
On the client node (172.27.12.3), I started qnet via:
mount -Tio-net npm-qnet.so
I verified qnet started by doing ‘ls /net’ and I saw my hostname there.
At this point doing an ‘ls /net’ on either the server or client should show the hostnames of BOTH machines. This indicates qnet is working.
I started gns in client mode via:
gns -c
On the server node I started the testServer program.
./testServer
On the client node I started the testClient program.
./testClient
And the Foo message appeared on the server and the Bar message on the client. So the name_attach worked fine across the network as expected.
Tim