【问题标题】:Message queue stack smashing消息队列堆栈粉碎
【发布时间】:2021-04-29 11:54:48
【问题描述】:

我正在尝试实现一个消息队列,并且我已经命名了一个进程服务器和另一个客户端(如您所见,我想坚持使用传统名称)。这是服务器上方的一段代码,您不需要关心它,因为它工作正常。我只是发布它以防它搞砸了整个工作。

我的实际问题是服务器应该如何知道客户端的 pid,因为如果没有使用 ftok 和 pid 作为函数参数的密钥就无法连接?

如果你想自己执行,你需要先运行服务器程序,然后再运行客户端程序(不需要cmd args)。 即使是最轻微的帮助,我也很感激。 提前谢谢大家。

//HEADER FILE NAMED : v1.h
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include <sys/stat.h>
#include<string.h>

#define N 95
#define STRLIM 60
#define PID 25922   
#define MSGQ_KEY 1234
#define REQ 1
#define RSP 2

#define REQ_SIZE (sizeof(struct request))
#define RSP_SIZE (sizeof(struct response))

struct request{
    long type;
    int mqid ;
    char* msg;
};

struct response{
    long type ;
    int res;
    char* msg;
};

int estab(char** contact);

int estab(char** contact){
char* test;
test="hi";
int ret;
ret=strcmp(*contact,test);
if(ret<0){
    return 1;
}
    return 0;
}//end of estab

//SERVER 
#include <fcntl.h>  
#include"v1.h"  

char** cat;
int fd;

int main(int argc, char const *argv[])
{   int i;
    int mqid;
    struct response rsp;
    struct request req;
        
    cat=(char**)malloc(sizeof(char*)*N);
    fd=open("dictionary.txt",O_RDONLY); 
    if(fd==-1){
        printf("fd error %d" , fd);
        perror("Error:");        
    }
    
    for(i=0;i<N;i++){
        cat[i]=(char*)malloc(sizeof(char)*STRLIM);
       
        read(fd,cat[i],40);
        printf("%s", cat[i]);
    }
    //////////////////end of char ** /////////////////
    int pid=getpid();
    key_t key=ftok("/home/myName/Desktop/as3/v1/v1s.c",PID);
    printf("The key is : %d",key);
    mqid=msgget(key,IPC_CREAT|S_IRWXU|IPC_NOWAIT);
        
    int ret=0;
    do{       
        msgrcv(mqid,&req,REQ_SIZE,0,0);   
        perror("its:");
        ret=estab(&req.msg);        
    }while(ret!=0);
    msgsnd(mqid,&rsp,RSP_SIZE,0);
    printf("connected");

   return 0;}//end of main 


#include"v1.h"

int main(int argc, char const *argv[])
{   int mqid,ret,pid;
    struct request req;
    struct response rsp={0};
  
    req.msg="hi";
    pid=getpid();
    printf("client's pid : %d",pid);
    pid=PID;
    mqid=msgget(MSGQ_KEY,0);

    msgsnd(mqid,&req,REQ_SIZE,0);

    do{
        msgrcv(mqid,&rsp,RSP_SIZE,0,0);
      
        ret=estab(&rsp.msg);
          
    }while(ret!=0);
    printf("connected from client!");
    return 0;
}

【问题讨论】:

  • 哪个程序崩溃了,客户端还是服务器?您收到的确切复制/粘贴错误是什么?您是否尝试过在调试器中运行问题程序以便查看崩溃的位置?
  • 当问题是“我如何获得PID”时,为什么标题是“消息队列堆栈粉碎”?
  • @Retired Ninja 当然! 检测到堆栈粉碎:终止,中止(核心哑)是确切的错误消息。 Gdb 报告在 .../raise.c:50 收到 SIGABRT 信号,并且该文件丢失。我尝试在遇到此帖子 stackoverflow.com/a/48287761/13052189 时安装所需的库,但我收到了第二步中显示的错误。感谢您的关注。

标签: c linux segmentation-fault message stack-smash


【解决方案1】:

服务器不能也不需要知道客户端的 pid。服务器首先启动,客户端稍后启动。所以在对服务端和客户端进行编码之前,我们需要先修复 ftok 的参数。函数ftok是

key_t ftok(const char *pathname, int proj_id);

第一个参数 pathname 是文件系统中现有且可访问的文件。第二个参数proj_id是一个整数,最后八位非零。

使用相同的 pathname 和 proj_id 值,我们可以在服务器和客户端生成(相同的)密钥。

客户端也应该为自己创建一个队列来接收来自服务器的回复。客户端可以将其消息中的消息队列 id 发送给服务器。服务器接收到消息,处理它并回复客户端发送的队列ID。

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    相关资源
    最近更新 更多