스파게티 한 젓가락/ 저붐 하시죠(msg qu, sender측)
글쓴이: indizarm / 작성시간: 화, 2003/11/11 - 6:05오후
당연하게 될거라고 생각했는데 안되니까 짜증이 밀려오는군요.
뭐가 잘못되었을까요? -_-;;
중간의 printf는 while(1)안에서의 block을 위해서(관찰용)
집어넣은 것입니다.
#include<stdio.h> // 표준 입출력을 위해 #include<sys/types.h> // types (정확치 않음) #include<sys/ipc.h> // System V IPC (semaphore, shared mem, msg qu) #include<sys/msg.h> // msg qu 관련 함수 사용을 위해 #include<time.h> // rand() 함수의 seed로 time()을 사용하기 위해 #include<stdlib.h> // rand() 함수의 사용을 위해 /*________________________________________________ clnt_three_module.c 형태: 무한정 또는 일정 횟수를 반복하면서 random number를 발생시키며, msg qu에 저장하고 읽어들여서 데이터를 화면으로 print한다. (중간에 시간 간격 둘 것) ________________________________________________*/ typedef struct { long type; // msgsnd()가 요구하는 형식에 맞추기 위한 dummy char str[30]; // 실제 데이터를 저장할 것 }MSG; int main(int argc, char* argv[]) { int mode; // 무한정 반복: 0, 일정횟수 반복: 1 int num_iteration; // 반복횟수 int i; // for문에서 사용되는 첨자 int snd_qu; // send용 msg qu. 반대쪽에서는 'rcv_qu' int rcv_qu; // recv용 msg qu. 반대쪽에서는 'snd_qu' int num_2send; // 생성해서 보낼 숫자 int num_recvd; // 받은 숫자 // char str_num[30]; // 데이터를 주고 받을 때 사용하는 버퍼 MSG str_num; if(argc == 1) { mode =0; } else { mode = 1; num_iteration = atoi(argv[1]); // 반복횟수 } srand((unsigned)time(NULL)); // time()을 seed로 snd_qu = msgget((key_t)1234,IPC_CREAT); // snd_qu 생성. 반대쪽에서는 'rcv_qu' rcv_qu = msgget((key_t)12340,IPC_CREAT); // rcv_qu 생성. 반대쪽에서는 'snd_qu' if(snd_qu == -1)printf("snd_qu 생성 실패\n"); if(mode == 0) { while(1) // 탈출방법은 없다. 오직 ctrl + c 만이... { num_2send = rand() % 1000000; // 숫자 생성 printf("Enter a num: "); scanf("%d",&num_2send); printf("\n"); str_num.type = 1; memset(str_num.str,'\0',30); // 버퍼 초기화 sprintf(str_num.str,"%d",num_2send); if(msgsnd(snd_qu, (MSG*)&str_num, 30, 0) == -1) { printf("msgsnd failed!\n"); // break; } else { memset(str_num.str,'\0',30); // 버퍼 초기화 if(msgrcv(rcv_qu, (void*)&str_num, 30, 0, 0) == -1) { printf("recv qu, empty!\n"); sleep(3); } num_recvd = atoi(str_num.str); printf("생성한 숫자:%d 받은 숫자:%d \n",num_2send,num_recvd); } } // End of 'while(1)' } else // mode = 1 { for(i=0; i<num_iteration; i++) { } // End of 'for(i=0;...' } // End of 'if(mode == 0)' if(msgctl(rcv_qu, IPC_RMID, 0) == -1) // msg qu 닫기 실패면 { printf("msg qu 닫기(IPC_RMID) 실패\n"); exit(1); } if(msgctl(snd_qu, IPC_RMID, 0) == -1) // msg qu 닫기 실패면 { printf("msg qu 닫기(IPC_RMID) 실패\n"); exit(1); } return 0; }
Forums:
mode가 없는거 같군요.
IPC_CREAT시에 mode값을 or 해주시지 않은것 같아 보이는군요.
========================================
* The truth will set you free.
mode는 그냥 666으로 되는 듯하던데요...그래서 그냥 뺐습니
mode는 그냥 666으로 되는 듯하던데요...
그래서 그냥 뺐습니다만... -_-?;;
What a Cool Days!!!
key 값의 문제.
snd_qu의 key값은 1234인데 rcv_qu의 key값은 12340 이네요.
서로 다른 메모리 키 값을 가지고 acess 하는 것이 문제라고 생각됩니다.
qu를 2개 사용하고 있는데요, 물론 구조가 조금 이상하다는것을 알기
qu를 2개 사용하고 있는데요, 물론 구조가 조금 이상하다는
것을 알기는 하지만, 우선 반대쪽 (그냥 '서버'라고 하겠습니다)
서버는 send thread와 recv thread로 이루어져 있고요,
(당연히 main()도 있고요... 그래서 편의상 3 modules라고...)
각각 버퍼와 msg qu를 가지고서 데이터를 보내거나 받습니다.
그렇기 때문에 위의 코드에서 snd_qu와 msg_qu가 서로 다
른 통로로 선언된 것입니다.
What a Cool Days!!!
그렇군요.
그래서 key값이 2개 였군여..
그런데..소스중에
위에 보면 msgget(...) 에 대한 error check가 없네요..
위의 소스만 가지고는 정상적으로 메모리 식별자를(snd_qu, rcv_qu)
얻어 냈는지 알수가 없습니다.
같은 시스템에서의 특정 key값에 대한 메모리 식별자 번호는 동일하므로
서버와 클라이언트에서 각각 메모리 식별자(snd_qu, rcv_qu)의 값을
찍어보시고 각각 동일한지 확인해 보세요..
물론 msgget에 대한 에러 유무도 확인해 보세요..
예 moonzoo님께서 말씀하신 것처럼 msgget()에 대한에러 체
예 moonzoo님께서 말씀하신 것처럼 msgget()에 대한
에러 체크도 하고, #include<errorno.h> 한다음에
errorno 도 찍어보고 그랬는데
EACCES 또는 Permission denied 또는 error 13번등이
발생하면서 msg qu 자체가 생성되지 않는군요.
ipcs -q 하면 아무것도 없는데도 말이죠... -_-;;
더욱 웃긴 것은 다른 소스 코드를 다운 받아서 그대로 실행
시켜도 똑같다는 것입니다. 윽
What a Cool Days!!!
..
EACCES 에러는..
일반적으로 key에 해당하는 메세지 큐가존재하며, 그래서 그 메세지 큐에 접근
하는 허가권을 갖고 있지 않을경우에 발생합니다..
ipcs -q 로 보이지 않는다니 난감--; 한데요..
KEY 값을 한번 바꿔보시면서( 만단위 이상의 숫자로..)
소스를 단순화 하여 msgget만 계속 테스트 해볼 수 밖에 없겠네요..
[quote]KEY 값을 한번 바꿔보시면서( 만단위 이상의 숫자로..)
억! 생각은 하고 있었지만.....
What a Cool Days!!!
댓글 달기