message passing over qnet

This topic has been discussed before on this forum but I haven’t found what I’m looking for.

In a nutshell I’m trying to access a message queue residing on a different node over qnet.

Qnet is running and working fine between the 2 nodes.

I’m using the example code from name_attach() which has appeared in this forum a couple of times (see below).

I’ve replaced the flags in name_attach() and name_open() with NAME_FLAG_ATTACH_GLOBAL.

The following has been executed on the server and client respectively:
gns -s
gns -c servername

The server code appears to work OK and I see the attach point on the server here:
/dev/name/global/net/servername/myname

However, name_open() on the client fails with:
‘error No such file or directory’.

A number of questions:

Do you need to setart gns and qnet in a certain order?

do I really need gns i.e. can I do this differently?

Has anyone a working example?

Many thanks in advance.

#define ATTACH_POINT “myname”

/* We specify the header as being at least a pulse */
typedef struct _pulse msg_header_t;

/* Our real data comes after the header */
typedef struct _my_data {
msg_header_t hdr;
int data;
} my_data_t;

/*** Server Side of the code ***/
int server() {
name_attach_t *attach;
my_data_t msg;
int rcvid;

/* Create a local name (/dev/name/local/…) */
if ((attach = name_attach(NULL, ATTACH_POINT, NAME_FLAG_ATTACH_GLOBAL)) == NULL) {
return EXIT_FAILURE;
}

/* Do your MsgReceive’s here now with the chid */
while (1) {
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);

   if (rcvid == -1) {/* Error condition, exit */
       break;
   }

   if (rcvid == 0) {/* Pulse received */
       switch (msg.hdr.code) {
       case _PULSE_CODE_DISCONNECT:
           /*
            * A client disconnected all its connections (called
            * name_close() for each name_open() of our name) or
            * terminated
            */
           ConnectDetach(msg.hdr.scoid);
           break;
       case _PULSE_CODE_UNBLOCK:
           /*
            * REPLY blocked client wants to unblock (was hit by
            * a signal or timed out).  It's up to you if you
            * reply now or later.
            */
           break;
       default:
           /*
            * A pulse sent by one of your processes or a
            * _PULSE_CODE_COIDDEATH or _PULSE_CODE_THREADDEATH
            * from the kernel?
            */
           break;
       }
       continue;
   }

   /* name_open() sends a connect message, must EOK this */
   if (msg.hdr.type == _IO_CONNECT ) {
       MsgReply( rcvid, EOK, NULL, 0 );
       continue;
   }

   /* Some other QNX IO message was received; reject it */
   if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX ) {
       MsgError( rcvid, ENOSYS );
       continue;
   }

   /* A message (presumable ours) received, handle */
   printf("Server receive %d \n", msg.data);
   MsgReply(rcvid, EOK, 0, 0);

}

/* Remove the name from the space */
name_detach(attach, 0);

return EXIT_SUCCESS;
}

/*** Client Side of the code ***/
int client() {
my_data_t msg;
int server_coid;

if ((server_coid = name_open(ATTACH_POINT, NAME_FLAG_ATTACH_GLOBAL)) == -1) {
    return EXIT_FAILURE;
}

/* We would have pre-defined data to stuff here */
msg.hdr.type = 0x00;
msg.hdr.subtype = 0x00;

/* Do whatever work you wanted with server connection */
for (msg.data=0; msg.data < 5; msg.data++) {
    printf("Client sending %d \n", msg.data);
    if (MsgSend(server_coid, &msg, sizeof(msg), NULL, 0) == -1) {
        break;
    }
}

/* Close the connection */
name_close(server_coid);
return EXIT_SUCCESS;

}

Are you sure because I don’t see any code that prints an error after the name_open. Always post the real code.

Mario,

Correct this was the sample code without my printf’s which I have working now.

I had to restart gns on the client again to make it work.

It appears that execution order of gns and qnet are important.

I’ll need to do further investigation.

However, do I need gns to get something like this to work.

In my design, these 2 nodes are tightly coupled and I may want both to act as server and client on different queues.

Do I need gns?

Many thanks.

I am not sure, but MsgSend must have argument 4 and 5 not null.

Yes, if you don’t know on what node the server/clients are running and you want a mecanism to automaticaly figure it out then you need gns. Unless you write your own method of discovery.