消息队列栈粉碎

Message queue stack smashing

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

我的实际问题是服务器应该如何知道客户端的 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。服务器首先启动,客户端稍后启动。所以我们需要在对server和client进行编码之前固定好ftok的参数。函数ftok是

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

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

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

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