2012-05-19 5 views
3

Linux 메시지 대기열을 사용하는 간단한 시간 서버와 클라이언트를 작성해야 할 때 할당이 있습니다. 서버는 메시지 대기열을 열고 클라이언트는 자신의 PID (유형 1의 메시지)와 함께 요청을 보내고 서버는 해당 메시지를 읽고 PID 유형 (읽은 메시지에서 가져온)의 메시지를 보냅니다. 내가 어디에서 실수를했는지 모르기 때문에 아래에 모든 코드를 넣었습니다. 나는 리눅스 프로그래밍 전문가가 아니다. 서버를 올바르게 작성했는지 알지 못합니다.Linux의 메시지 대기열에서 읽을 때 "주소가 잘못되었습니다."

서버와 클라이언트가 포함하는 파일입니다.이 방법으로 작성해야합니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/msg.h> 
#include <sys/ipc.h> 
#include <sys/types.h> 
#include <string.h> 
#include <signal.h> 

#define QUEUE 100 
#define PERM_ALL 0777 

typedef struct my_msgbuf { 
    long mtype; 
    int pid; 
} ClientMessage; 

typedef struct my_msgbuf2 { 
    long mtype; 
    struct tm time; 
} TimeMessage; 

서버

int m_queue; 

void cleanup(int signum) { 
    if (msgctl(m_queue, IPC_RMID, NULL) == -1) { 
     printf("Something happen on clean up\n"); 
     exit(1); 
    } 
    exit(signum); 
} 

int main() { 
    ClientMessage pid_message; 
    TimeMessage t; 
    time_t clock; 
    struct tm *cur_time; 

    if ((m_queue = msgget(QUEUE, PERM_ALL | IPC_CREAT)) == -1) { 
     printf("Can't create and open message queue\n"); 
     exit(1); 
    } 
    printf("created message queue = %d\n", m_queue); 
    fflush(stdout); 
    //t = malloc(sizeof(TimeMessage)); 
    signal(SIGINT, cleanup); 

    while (1) { 
     if (msgrcv(m_queue, &pid_message, sizeof(pid_message.pid), 1, 0) == -1) { 
      break; 
     } else { 
      t.mtype = pid_message.pid; 
      clock = time(NULL); 
      cur_time = localtime(&clock); 
      memcpy(&t.time, cur_time, sizeof(struct tm)); 
      msgsnd(m_queue, &t, sizeof(struct tm), 0); 
     } 
    } 

    cleanup(0); 
} 

클라이언트

int main() { 
    int m_queue; 
    TimeMessage *t; 
    ClientMessage client; 

    if ((m_queue = msgget(QUEUE, PERM_ALL)) == -1) { 
     perror("Error in opening queue"); 
     exit(1); 
    } 

    client.mtype = 1; 
    client.pid = getpid(); 

    while (1) { 
     if (msgsnd(m_queue, &client, sizeof(client.pid), 0) == -1) { 
      perror("Error sending to queue"); 
      exit(1); 
     } else { 
      if (msgrcv(m_queue, t, sizeof(struct tm), client.pid, 0) == -1) { 
       perror("Error reading from queue"); 
       exit(1); 
      } 
      printf("time: %d:%d:%d\n", t->time.tm_hour, t->time.tm_min, t->time.tm_sec); 
     } 
    } 
    return 0; 
} 

두 프로그램이 오류없이 컴파일하지만 위해 msgrcv 클라이언트 복귀 "큐에서 읽기 오류"-1을 반환합니다.

+1

제안 :'errno' (당신의 경우 메시지 큐 API처럼)를 설정하는 API로 작업 할 때 [perror' 또는'strerror']를 사용하는 것이 좋습니다. (http://beej.us/guide /bgnet/output/html/multipage/perrorman.html) –

+0

thanks @ another.anon.coward 나는 왜 예제가 perror를 사용하는지 궁금했다. – jcubic

+0

msgrcv는 "잘못된 주소"를 반환한다 – jcubic

답변

5

perror를 추가 한 후에 당신이 "주소는 인 msgp (버퍼)에 액세스 할 수 없습니다가 가리키는"을 의미 "Bad Address" (EFAULT)을 알리는 오류를 가지고 나타납니다. 코드에서 TimeMessage *t에 할당 된 메모리가 없으므로 메모리를 할당하거나 TimeMessage t으로 변경하고 t에서 msgrcv 대신 &t을 전달하면됩니다. 또한 크기가이 도움이
희망 (분명 그에 따라 printf 문을 바꿀 것 &) sizeof t (t*t에서의 변화를 가정, 또는 sizeof(TimeMessage)*t에 대한) 대신 sizeof(struct tm)해야합니다!

+0

고마워,'t = malloc (sizeof (TimeMessage));'를 추가하면 효과가있다. – jcubic

관련 문제