System-V IPC

ewillwin·2022년 6월 1일
0

System Programming Lab

목록 보기
10/15
post-thumbnail

Make chatting program using Message Queue

  • You must run 2 programs(users).
  • When each program starts, get sender's id and receiver's id from stdin
  • Sender: Gets the message from stdin and sends the message to the receiver's id
  • Receiver: Receives message from other sender/ print out the message
  • There should be no wait between sending normal message and receiving ack message (at sender)
  • Quit the program if the user inputs "quit"
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>

pid_t sender, receiver;

void handler(int sig)
{
	exit(0);
}

struct msgbuf{
	long msgtype;
	char text[256];
};

int main()
{
	signal(SIGINT, handler);

	int sent_id_int, recv_id_int;
	char *send_id = NULL;
	char *recv_id = NULL;
	size_t size;

	printf("MY id:");
	getline(&send_id, &size, stdin);
	send_id[size-1] = '\0';

	printf("Receiver's id:");
	getline(&recv_id, &size, stdin);
	recv_id[size-1] = '\0';

	key_t send_k = ftok(".", atoi(send_id));
	key_t recv_k = ftok(".", atoi(recv_id));

	int send_qid = msgget(send_k, IPC_CREAT | 0660);
	int recv_qid = msgget(recv_k, IPC_CREAT | 0660);
	if(send_qid == -1 || recv_qid == -1){
		perror("msgget error");
		exit(0);
	}

	sender = getpid();
	if((receiver = fork()) == 0){ //Child - Receiver
		//struct msgbuf *msg = malloc(sizeof(struct msgbuf));

		while(1){
		
			struct msgbuf *msg = malloc(sizeof(struct msgbuf));
			if(msgrcv(send_qid, (void *)msg, sizeof(struct msgbuf), 1, 0) == -1){
				perror("msgrcv error");
				exit(0);
			}
			if(strcmp(msg->text, "quit\n") == 0){
				printf("QUIT\n");
				kill(sender, SIGINT);
				free(msg);
				exit(0);
			}
			printf("RECEIVED: %s", msg->text);

			free(msg);
		}
	}
	else{ //Parent - Sender

		while(1){
			struct msgbuf *msg = malloc(sizeof(struct msgbuf));
			msg->msgtype = 1;

			char *message = NULL;
			size_t messagesize;
			getline(&message, &messagesize, stdin);
			message[messagesize-1] = '\0';
			//if(strcmp(message, "quit\n") == 0){
			//	printf("QUIT\n");
			//	break;
			//}
			strcpy(msg->text, message); //write message

			if(msgsnd(recv_qid, (void *)msg, sizeof(struct msgbuf), 0) == -1){
				perror("msgsnd error");
				exit(0);
			}
			if(strcmp(msg->text, "quit\n") == 0){
				printf("QUIT\n");
				kill(receiver, SIGINT);
				break;
			}
			

			free(msg);
		}
	}
}

-> void handler 함수 만들고
-> signal(SIGINT, handler)
kill(sender, SIGINT), kill(receiver,SIGINT)로 parent process가 먼저 죽어도 child process가 signal 받고 죽을 수 있도록 설정함

profile
💼 Software Engineer @ LG Electronics | 🎓 SungKyunKwan Univ. CSE

0개의 댓글