'QNX IPC'에 해당되는 글 1건

MsgSend, MsgReceive, MsgReply를 이용한 client - server sample

MsgSend는 함수명만 보면 보내기만 할것 같지만, 실제로는 받는것도 하고 있다. Client - Server 모델에서 echo 서버 형태를 구현한다고 하면 client쪽에서는 send 이후 receive로 받아오는데, 이때 receive할때까지 client는 기다린다. MsgSend는 send, receive를 합한 형태로 보면 된다. 그렇기 때문에 MsgSend는 데이터를 받아올때까지 Blocking되는 특성이 있다. 함수 원형은 아래와 같다. 

#include <sys/neutrino.h>

int MsgSend (int coid,
             const void *smsg,
             int sbytes,
             void *rmsg,
             int rbytes);

 

coid : ConnectAttach()를 통해서 나온 값

smsg : 보내는 데이터

sbytes : 보내는 데이터의 길이

rmsg : 받는 데이터

rbytes : 받는 데이터의 길이 

 

MsgReceive는 데이터를 받는 함수이고, MsgReply는 응답을 하는 함수이다. sample을 보면 이해가 갈것이다.

//Server.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/neutrino.h>

#define EOK 1234
int main(void)
{
    int     rcvid;         // indicates who we should reply to
    int     chid;          // the channel ID
    char    message [512]; // big enough for our purposes

	printf("Server Start\n");

    // create a channel
    chid = ChannelCreate (0);
	printf("Wait in channel %d\n",chid);

    // this is typical of a server:  it runs forever
    while (1) {

        // get the message, and print it
        rcvid = MsgReceive (chid, message, sizeof (message),
                            NULL);
        printf ("Got a message, rcvid is %X\n", rcvid);
        printf ("Message was \"%s\".\n", message);

        // now, prepare the reply.  We reuse "message"
        strcpy (message, "This is the reply");
        MsgReply (rcvid, EOK, message, sizeof (message));
    }

	return 0;
}

서버쪽에서는 ChannelCreate로 chid를 가져오고, Client는 여기에 Attach한다. 

//client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/neutrino.h>

int main(int argc, char *argv[]){
	char *smsg = "This is the outgoing buffer";
	char rmsg [200];
	int coid;
	int ret;
	pid_t pid;

	if(argc != 2){
		fprintf(stderr,"Usage : %s [server_pid] \n",argv[0]);
		exit(EXIT_FAILURE);
	}
	pid = atoi(argv[1]);
	// establish a connection
	coid = ConnectAttach (0, pid, 1, 0, 0);
	if (coid == -1) {
		fprintf (stderr, "Couldn't ConnectAttach to %d/%d/%d!\n", 0, pid, 1);
		perror (NULL);
		exit (EXIT_FAILURE);
	}

	// send the message
	if ((ret  = MsgSend (coid,
				smsg,
				strlen (smsg) + 1,
				rmsg,
				sizeof (rmsg))) == -1) {
		fprintf (stderr, "Error during MsgSend\n");
		perror (NULL);
		exit (EXIT_FAILURE);
	}

	if (strlen (rmsg) > 0) {
		printf ("Process ID %d returns code :%d, msg :\"%s\"\n", pid, ret, rmsg);
	}
}

 

여기서 ConnectAttach의 channel id는 1로 임의로 지정했는데, argv로 입력받는 것이 더 좋을듯하다. 난 귀찮아서...

반응형
블로그 이미지

REAKWON

와나진짜

,