2016-12-06 51 views
0

我正在做消息隊列的第一次練習。我想mq_receive來阻止,所以我沒有打開O_NOBLOCK。mq_receive消息太長 - 沒有消息發送

mq_receive方法正在返回,並且perror()正在打印「消息太長」。這是我甚至發出信息之前。

的ATM發送消息:

void* run_ATM(void* arg) { 
    int status; 

    char accountNumber[15]; 
    cout << "ATM is running" << endl; 
    cout << "Please input an account number > "; 
    cin >> accountNumber; 
    status = mq_send(PIN_MSG, accountNumber, sizeof(accountNumber), 1); 

} 

數據庫接收它們

void* run_DB(void* arg){ 
    cout << "Database server running" << endl; 
    int status; 
    char received_acct_number[30]; 

    while(1){ 
     status = mq_receive(PIN_MSG, received_acct_number, 100, NULL); 
     if (status < 0){ 
      perror("error "); 
     } else { 
      cout << "received account number\t" << received_acct_number << endl; 
     } 
    } 
} 

這只是初步的代碼 - 所以它最終將做得更多。我只想得到一個基本的工作例子。

編輯:所需的其他代碼得到這個運行:

#define PIN_MSG_NAME "/pin_msg" 
#define DB_MSG_NAME "/db_msg" 

#define MESSAGE_QUEUE_SIZE 15 

pthread_t ATM; 
pthread_t DB_server; 
pthread_t DB_editor; 
void* run_ATM(void* arg); 
void* run_DB(void* arg); 

static struct mq_attr mq_attribute; 
static mqd_t PIN_MSG, DB_MSG; 

int main(int argc, char const *argv[]) 
{ 
    pthread_attr_t attr; 


    mq_attribute.mq_maxmsg = 10; //mazimum of 10 messages in the queue at the same time 
    mq_attribute.mq_msgsize = MESSAGE_QUEUE_SIZE; 

    PIN_MSG = mq_open(PIN_MSG_NAME, O_CREAT | O_RDWR, 0666, &mq_attribute); 
    DB_MSG = mq_open(DB_MSG_NAME, O_CREAT | O_RDWR, 0666, &mq_attribute); 

    pthread_attr_init(&attr); 
    pthread_attr_setstacksize(&attr, 1024*1024); 

    long start_arg = 0; //the start argument is unused right now 
    pthread_create(&ATM, NULL, run_ATM, (void*) start_arg); 
    pthread_create(&DB_server, NULL, run_DB, (void*) start_arg); 

    pthread_join(ATM, NULL); 
    pthread_join(DB_server, NULL); 
} 

接收緩衝區小於消息隊列的大小大,所以應該沒有問題吧?

+2

你能給我們足夠的代碼來複制這個問題嗎?例如,什麼是'MESSAGE_QUEUE_SIZE'?什麼是PIN_MSG? –

回答

2

如果您檢查函數返回的錯誤並將其打印出來,錯誤將會很明顯。您正在將accountNumberPIN轉換爲指針而不是轉換其地址。你想:

status = mq_send(PIN_MSG, (const char*) &accountNumber, MESSAGE_QUEUE_SIZE, 1); 

status = mq_send(PIN_MSG, (const char*) &PIN, MESSAGE_QUEUE_SIZE, 1); 

status = mq_receive(PIN_MSG, (char*) &received_acct_number, 100, NULL); 

status = mq_receive(PIN_MSG, (char*) &received_PIN, MESSAGE_QUEUE_SIZE, NULL); 

注意,仍然有很多與我們的代碼,最值得注意的是,你通過不正確地處理它們的尺寸超限這些變量的事實問題。您可以排序的解決這個問題是這樣的:

status = mq_send(PIN_MSG, (const char*) &accountNumber, sizeof (accountNumber), 1); 

status = mq_send(PIN_MSG, (const char*) &PIN, sizeof (PIN), 1); 

status = mq_receive(PIN_MSG, (char*) &received_acct_number, sizeof(received_acct_number), NULL); 

status = mq_receive(PIN_MSG, (char*) &received_PIN, sizeof(received_PIN), NULL); 

不過說真的,你應該有某種消息格式,你應該系列化你的消息,並從該格式。

+0

你是什麼意思創建一個消息格式?我應該把數字封裝在某些東西中嗎? –

+0

@BrydonGibson我的意思是,如果你要發送消息,你應該有一些記錄的格式來解釋它們是如何發送的。例如,如果格式是每個消息都是100個字節,那麼您是否需要一個100字節的緩衝區來接收它們?或者這些消息應該有多大? –

+0

將大小更改爲'sizeof(thingBeingSent)'保持mq_receive不被阻塞。它返回-1,'perror()'打印'Message too long' –

-1

所以它看起來像一個剩餘的消息隊列的主要問題,因爲他們沒有正確關閉/取消鏈接的代碼。

我原來的代碼中有一些錯誤,我很欣賞指出並給出解決方案的答案。

當試圖改變消息的格式時,我想再次調用mq_open時,它不會改變消息大小(因爲消息隊列已經存在)。這會導致代碼中的大小錯誤。重新啓動是一個解決方法,但解決方案是妥善清理與mq_unlink()然後mq_close()