使用消息队列的C中的服务器和客户端(无套接字代码)

时间:2015-11-14 01:58:25

标签: c server pthreads client ipc

我正在尝试在客户端和服务器程序中实现线程,二进制信号量和消息队列。一切正常,除了我的服务器中的回复,以将响应发送回客户端。当我取消注释回复时,服务器在收到消息后无限循环。

它们都使用message.h头文件,该文件是包含以下内容的结构: contents(字符),id(int)和mtype(int)。

// server.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#include "message.h"


int sqid, cqid, pid;
msg m, n;
sem_t sem_var;
key_t key;


void requestSem();
void setSem();
void unlockSem();
void reply();
void readQueue();
void listener(void *ptr);


int main() {

    key = ftok(".", 'z');
    sqid = msgget(key, IPC_CREAT | 0600);

    if(sqid < 0) {
        perror("Error creating the message queue.\n");
}

pthread_t thread1;
pthread_t thread2;
pthread_t thread3;

char *msg1 = "Thread 1";
char *msg2 = "Thread 2";
char *msg3 = "Thread 3";

pthread_create(&thread1, NULL, (void *) &listener, (void *) msg1);
pthread_create(&thread2, NULL, (void *) &listener, (void *) msg2);
pthread_create(&thread3, NULL, (void *) &listener, (void *) msg3);

pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);

}

// always listen for messages

void listener(void *ptr) {

while (1) {

requestSem();
setSem();
readQueue();
unlockSem();
//reply();

    }
}

void readQueue()
{

// print the proccess ID and thread ID

printf("Process ID: %d, Thread ID: %d\n", getpid(), pthread_self());

// receive message

if(msgrcv(sqid,&m,sizeof(struct msg),0,0) < 0) {
    perror("Error receiving a message.\n");
}
printf("Message was received...\n");
fprintf(stderr, "The contents are: %s\n", &m.contents);
fprintf(stderr, "The client's ID is: %d\n", (&m)->id);
fprintf(stderr, "The thread's ID is: %d\n", pthread_self());

}




void requestSem()
{
// request semaphore (lock)

sem_init(&sem_var, 1, 1);

printf("Semaphore requested.\n");

}

void setSem()
{
// lock semaphore

sem_wait(&sem_var);

printf("Semaphore set.\n");

}

void unlockSem()
{
// unlock semaphore

sem_post(&sem_var);

printf("Semaphore unlocked.\n");
}

void reply()
{
// send reply

printf("got here\n");

pid = (&m)->id;

cqid = msgget(pid, 0600);

n.contents = (&m)->contents;
n.mtype = 0;
n.id = getpid();

if(msgsnd(cqid, &n,sizeof(struct msg),0) < 0) {
    perror("Msg send error");
}

msgctl(sqid,IPC_RMID,NULL);

}

// client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>

#include "message.h"



int main() {

// initialize variables

int mqid, rqid;
msg m;
key_t key;

// initialize message

int pid;
pid = getpid();
m.id = pid;
m.mtype = 1;

// create message queue and response queue

key = ftok(".", 'z');
mqid = msgget(key, 0600);
rqid = msgget(pid, IPC_CREAT | 0600);

if(mqid < 0) {
    perror("Error creating the message queue.\n");
}

if (rqid < 0)
{
    perror("Error creating the message queue.\n");
}

// loop forever, can send as many messages as you want

while(1) {

fprintf(stderr, "The ID of the client is: %d\n", pid);

// prompt for user input

printf("Enter one character to send: \n");
scanf("%s", &m.contents);

// send message

if(msgsnd(mqid, &m,sizeof(struct msg), 1) < 0) {
    perror("Error sending the message.");
}

//msgctl(mqid,IPC_RMID,NULL);

printf("Message was sent successfully!\n");

// receive response

printf("Waiting for a reply...\n");

if(msgrcv(rqid,&m,sizeof(msg), 0, 0) < 0)
{
    perror("Error receiving a message.\n");
}

printf("Message was received.\n");
fprintf(stderr, "The contents are: %s\n", &m.contents);

    }
}

提前感谢您的帮助。当回复在服务器的监听器中被注释掉时,一切都正常运行。取消注释会产生无限循环。

1 个答案:

答案 0 :(得分:0)

服务器永不退出的原因是因为每个线程都有

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000145201ac0
Triggered by Thread:  7

Thread 7 name:
Thread 7 Crashed:
0   libsystem_platform.dylib        0x0000000199e36220 _platform_memmove + 48 (memmove.s:220)
1   CoreImage                       0x0000000184e86e4c CI::GLTextureManager::texture_for_CGImage(CGImage*, CI::PixelFormat) + 372 (context-gles.cpp:910)
2   CoreImage                       0x0000000184e8a310 CI::GLContext::bind_textures(CI::SerialObjectPtrArray*, CI::Kernel*) + 240 (context-gles.cpp:3060)
3   CoreImage                       0x0000000184e899e0 CI::GLContext::render_apply_node(CI::Node const*, bool) + 160 (context-gles.cpp:2699)
4   CoreImage                       0x0000000184e897fc CI::GLContext::recursive_render(CI::Node*, bool) + 912 (context-gles.cpp:2379)
5   CoreImage                       0x0000000184e8a788 CI::GLContext::render(CI::Node*) + 180 (context-gles.cpp:2880)
6   CoreImage                       0x0000000184e9bfec CI::_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*) + 676 (render.cpp:2622)
7   CoreImage                       0x0000000184e9bc9c CI::image_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*, unsigned long) + 664 (render.cpp:2680)
8   CoreImage                       0x0000000184ea08e8 copyImageBlockSetOptsCallback(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 856 (imageProvider.h:143)
9   CoreGraphics                    0x0000000184af2198 CGImageProviderCopyImageBlockSet + 220 (CGImageProvider.c:500)
10  ImageIO                         0x0000000185baa41c GetBytesImageProvider + 484 (CGImagePixelDataProvider.c:382)
11  ImageIO                         0x0000000185c40440 _CGImagePluginWriteAppleJPEG + 2444 (imageAppleJPEG.c:2785)
12  ImageIO                         0x0000000185ba3020 CGImageDestinationFinalize + 724 (CGImageDestination.c:2119)
13  MyAppNameHere                   0x0000000100096468 _TFC11 MyAppNameHere 12PhotoEditor15fullImageOutputfS0_FT_GSqCSo22PHContentEditingOutput_ + 1272 (PhotoEditor.swift:71)
14  MyAppNameHere                   0x0000000100113310 _TFFFFFC11 MyAppNameHere 36PhotosPickerCollectionViewController16editSingleAssetFS0_FCSo7PHAssetT_U_FT_T_U0_FTGSqCSo21PHContentEditingInput_GVSs10DictionaryCSo8NSObjectPSs9AnyObject___T_U_FT_T_U_FT_T_ + 172 (PhotosPickerCollectionViewController.swift:851)
15  libdispatch.dylib               0x0000000199c296e8 _dispatch_call_block_and_release + 24 (init.c:761)
16  libdispatch.dylib               0x0000000199c296a8 _dispatch_client_callout + 16 (object.m:513)
17  libdispatch.dylib               0x0000000199c37b40 _dispatch_root_queue_drain + 2140 (inline_internal.h:1063)
18  libdispatch.dylib               0x0000000199c372dc _dispatch_worker_thread3 + 112 (queue.c:4250)
19  libsystem_pthread.dylib         0x0000000199e3d470 _pthread_wqthread + 1092 (pthread.c:1990)
20  libsystem_pthread.dylib         0x0000000199e3d020 start_wqthread + 4 (pthread_asm.s:191)

循环,无法退出该循环