스파게티 한 젓가락/ 저붐 하시죠(msg qu, sender측)

indizarm의 이미지

당연하게 될거라고 생각했는데 안되니까 짜증이 밀려오는군요.

뭐가 잘못되었을까요? -_-;;

중간의 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;
}
sunyzero의 이미지

IPC_CREAT시에 mode값을 or 해주시지 않은것 같아 보이는군요.

========================================
* The truth will set you free.

indizarm의 이미지

mode는 그냥 666으로 되는 듯하던데요...

그래서 그냥 뺐습니다만... -_-?;;

What a Cool Days!!!

moonzoo의 이미지

snd_qu = msgget((key_t)1234,IPC_CREAT);    // snd_qu 생성. 반대쪽에서는 'rcv_qu' 
   rcv_qu = msgget((key_t)12340,IPC_CREAT);   // rcv_qu 생성. 반대쪽에서는 'snd_qu' 

snd_qu의 key값은 1234인데 rcv_qu의 key값은 12340 이네요.

서로 다른 메모리 키 값을 가지고 acess 하는 것이 문제라고 생각됩니다.

indizarm의 이미지

qu를 2개 사용하고 있는데요, 물론 구조가 조금 이상하다는
것을 알기는 하지만, 우선 반대쪽 (그냥 '서버'라고 하겠습니다)
서버는 send thread와 recv thread로 이루어져 있고요,
(당연히 main()도 있고요... 그래서 편의상 3 modules라고...)
각각 버퍼와 msg qu를 가지고서 데이터를 보내거나 받습니다.
그렇기 때문에 위의 코드에서 snd_qu와 msg_qu가 서로 다
른 통로로 선언된 것입니다.

What a Cool Days!!!

moonzoo의 이미지

그래서 key값이 2개 였군여..

그런데..소스중에

snd_qu = msgget((key_t)1234,IPC_CREAT);    // snd_qu 생성. 반대쪽에서는 'rcv_qu' 
   rcv_qu = msgget((key_t)12340,IPC_CREAT);   // rcv_qu 생성. 반대쪽에서는 'snd_qu' 

위에 보면 msgget(...) 에 대한 error check가 없네요..

위의 소스만 가지고는 정상적으로 메모리 식별자를(snd_qu, rcv_qu)

얻어 냈는지 알수가 없습니다.

같은 시스템에서의 특정 key값에 대한 메모리 식별자 번호는 동일하므로

서버와 클라이언트에서 각각 메모리 식별자(snd_qu, rcv_qu)의 값을

찍어보시고 각각 동일한지 확인해 보세요..

물론 msgget에 대한 에러 유무도 확인해 보세요..

indizarm의 이미지

예 moonzoo님께서 말씀하신 것처럼 msgget()에 대한
에러 체크도 하고, #include<errorno.h> 한다음에
errorno 도 찍어보고 그랬는데

EACCES 또는 Permission denied 또는 error 13번등이
발생하면서 msg qu 자체가 생성되지 않는군요.

ipcs -q 하면 아무것도 없는데도 말이죠... -_-;;

더욱 웃긴 것은 다른 소스 코드를 다운 받아서 그대로 실행
시켜도 똑같다는 것입니다. 윽

What a Cool Days!!!

moonzoo의 이미지

EACCES 에러는..

일반적으로 key에 해당하는 메세지 큐가존재하며, 그래서 그 메세지 큐에 접근

하는 허가권을 갖고 있지 않을경우에 발생합니다..

ipcs -q 로 보이지 않는다니 난감--; 한데요..

KEY 값을 한번 바꿔보시면서( 만단위 이상의 숫자로..)

소스를 단순화 하여 msgget만 계속 테스트 해볼 수 밖에 없겠네요..

indizarm의 이미지

Quote:
KEY 값을 한번 바꿔보시면서( 만단위 이상의 숫자로..)

소스를 단순화 하여 msgget만 계속 테스트 해볼 수 밖에 없겠네요..

억! 생각은 하고 있었지만.....

What a Cool Days!!!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.