차량(전장) SW/QNX
[QNX] MsgSend와 MsgReceive, MsgReply로 통신 sample
REAKWON
2022. 9. 29. 17:34
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로 입력받는 것이 더 좋을듯하다. 난 귀찮아서...
반응형