name_open() question?

from this server example code, when client calls name_open() to connect to this server the server never receives _IO_CONNECT message. So I don’t see this code executing? Any know why?

   if (msg.hdr.type == _IO_CONNECT ) {
       printf("Client Connected\n");
       MsgReply( rcvid, EOK, NULL, 0 );
       continue;
   }

#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;

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, 0)) == 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?
    */
       }
       continue;
   }

   /* name_open() sends a connect message, must EOK this */
   if (msg.hdr.type == _IO_CONNECT ) {
       printf("Client Connected\n");
       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;
}

Works for me (just tried it), Are you sure the name_open worked. What version of OS are you using?

Jinma,

Interesting how much this looks the example code from name_attach() ;)

Honestly, you’ve copied the code directly from the example. There’s no reason it shouldn’t work.

Two things:

  1. What happens on your client example. Does it successfully attach to the server?

  2. If you add another printf after the MsgReceive() call and print out the rcvid value what do you get (assuming the MsgReceive) gets called at all.

I can tell you I use almost this exact code verbatim in one of my servers and I definitely see that code get called all the time when clients attach. The only real difference is I use the thread safe versions (MsgReceive_r, MsgReply_r etc) of the functions listed in the example code.

Tim

Ok here is my code instead of the text version. I just made everything simple where client will just try to do attach_open and server will receive that message and printf connected. But server prints 0 for rcvid? I guess it’s getting that when client terminates. I am using QNX 6.3 and developing from windows momentics with target connections

Client code which just connects to MsgServer:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/dispatch.h>

#define ATTACH_POINT “MsgServer”
typedef struct _pulse msg_header_t;

typedef struct _my_data
{
msg_header_t hdr;
int data;
} my_data_t;

int main(int argc, char *argv[])
{
int fd;
if ((fd = name_open(ATTACH_POINT, 0)) == -1) {
printf(“failed\n”);
return EXIT_FAILURE;
}
printf("%d\n",fd);
printf(“connected to server\n”);

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

}

My server code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/dispatch.h>

#define ATTACH_POINT “MsgServer”

/* 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;

int main(int argc, char *argv[])
{
name_attach_t *attach;
my_data_t msg;
int rcvid; //indicates who we should reply to

/* Create a local name (/dev/name/local/…) /
if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL)
{
return EXIT_FAILURE;
}
while(1)
{
//get the message and print it
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);
printf("%d\n",rcvid);
if (rcvid == -1) {/
Error condition, exit */
break;
}
if (msg.hdr.type == _IO_CONNECT)
{
printf(“connected\n”);
MsgReply( rcvid, EOK, NULL, 0 );
continue;
}

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

return EXIT_SUCCESS;
}

Got it!

You probably don’t have gns (Global Name Server) running. Local name will work without it, but apparently you don’t get the _IO_CONNECT message.

-MArio

but I thought by default it’s a local name and I confirmed my server name in /dev/name/local/ directory not global? But I’ll try running gns in any case. Just to let you know, my client is running in the same machine as my server.

yeh… it works now… hmmmm but I don’t understand why I have to gns when I am all local? And I haven’t told name_attach to make it global?

naver mine. I guess gns should run in either case according to the doc. So is gns an optional service that is executed only if we make it to? or should it have started automatically from default OS installation?
Thanks mario.

It’s not started by default. Note that you don’t have to start it, unless your design needs that IO_CONNECT message.