2 u012122743 u012122743 于 2014.11.30 22:31 提问

利用有名管道创建简易的服务器客户端模型

主要思路:建立一个公共的管道,所有与服务器建立连接的先要通过这个管道相服务器发送消息,然后服务器以客户端的前 4 个字符与特定的字符拼接形成新的有名管道,与之交互.最后全部关闭

出现的debug:
Sever.c fork之后父进程将子进程的id号码传递过去,然后已这个pid当做服务器的 id号<这样服务器才可以与客户端进行交互>, 在里面我使用了 raise函数表明 signal 函数讲SIGUSR1信号安装好了,但是为什么不调用 handler函数呢?代码如下
Sever.c
#include
#include
#include
#include
#include
#include
#include
#include

void handler(int);

void handler(int p)
{
pid_t pid; //fork的返回值.
int sss; //打开的文件描述符.
int res;
char tmp[] = {'\0'}; //发送给子进程的信息.
char temp[128] = {"/tmp/"}; //生成管道的目录.
char Temp[5] = {'\0'};

int i = 0; //用作下标,已当作最后名称.

printf("zero\n");

pid = fork();
//服务器从管道接收到来自客户端的消息,然后服务器发送一个消息给客户端.

if(pid == 0)
{
//用类似于tcp数据包的方式来发送.<在发送消息的前面几个字节来说明建造的管道名称>

    res = open("/tmp/pipe",O_RDONLY);           //以只读的方式打开.

    close(res);

    read(res,tmp,128);                  //读取128个字节.

    printf("the msg rec form client is %s\n",tmp);

    for(;i < 4;i++)
        Temp[i] = tmp[i];           //已输入的前面4个字节当做名称.

    strcat(temp,Temp);

    printf("Temp = %s\n",Temp);
    printf("temp = %s\n",temp);

    sss = mkfifo(temp, O_CREAT | O_RDWR );

    printf("sss = %d\n",sss);

    if(sss < 0)
    {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }

    sss = open(temp,O_RDWR);

    memset(tmp,'\0',sizeof(tmp));

    write(sss,tmp,sizeof(tmp));

    close(sss);

    unlink(temp);

    sss = 0;

}
else if(pid > 0)            //父进程只需要等待子进程消亡.
{
    waitpid(pid);
}
else
{
    perror("fork");
    exit(-1);
}

}

int main(int argc,char **argv)
{
int res;
int fd[2];
pid_t pid;

//setsid();     //让其成为一个组长进程,就可以接收到信号了,而不是让原来调用它的bash终端接收进程.

pipe(fd);

pid = fork();

if(pid > 0)
{
    //printf("child id is %d\n",pid);
    write(fd[1],&pid,sizeof(pid_t));

    close(fd[1]);

    pause();

    waitpid(pid);


}
else
{
    signal(SIGUSR1,handler);

    printf("the parent id is %d\n",getpid());

    read(fd[0],&pid,sizeof(pid_t));

    printf("the sever id is %d\n",pid);

    res = mkfifo("/tmp/pipe",O_CREAT | O_RDWR |S_IRWXU );

    if(res < 0)
    {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }

    //raise(SIGUSR1);

    while(1)
    {
        printf("haha\n");
        printf("waiting signal\n");
        pause();
        printf("rec signal\n");
    }
}

return 0;

}

Client.c
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc,char **argv)
{
int fd = 0;
int sig = 0;
int i = 0;
char tmp[5] = {'\0'};
char name[128] = {"/tmp/"};
char msg[128] = {'\0'};

printf("plx input the id of the sever:\n");
scanf("%d",&sig);

kill(SIGUSR1,sig);

printf("signal send\n");

sleep(1);

fd = open("/tmp/pipe",O_WRONLY);

if(fd < 0)
{
    perror("open");
    exit(EXIT_FAILURE);
}

printf("plx input you want send to sever infor:\n");
scanf("%s",msg);

for(;i<4;i++)
    tmp[i] = msg[i];

write(fd,msg,strlen(msg));

close(fd);

sleep(1);

memset(msg,'\0',strlen(msg)+1);

strcat(name,tmp);

fd = open(name,O_RDONLY);
if(fd < 0)
{
    perror("open");
    exit(EXIT_FAILURE);
}

read(fd,msg,strlen(msg));

printf("i rec the msg from Sever:%s\n",msg);

close(fd);

return 0;

}
希望各位大神多多帮助,多谢

1个回答

erhou134
erhou134   Rxr 2014.12.01 10:41

不要在信号处理中fork
也建议最好不要在信号处理中进行复杂操作

u012122743
u012122743 恩,可是这个问题怎么解决呢?有什么好的办法呢?
接近 3 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片