关闭

linux下使用共享内存实现客户端/服务器

标签: linux
461人阅读 评论(0) 收藏 举报
分类:

在共享内存的使用中,顾名思义,就是实现多个进程中使用同一个内存区域来实现数据的通信。这样就可以实现一个简单的客户端/服务器程序啦。
共享内存使用的函数有下面几个:

void* shmat(int shm_id , const void* shm_addr , int shmflg);
int chmctl(int shm_id , int cmd , struct shmid_ds* buf);
int shmdt(const void* shm_addr);
int shmget(key_t key , size_t size , int shmflg);

1.shmget()函数是用来创建一个共享内存区域的。和信号量一样,需要提供一个key来作为内存段的命名。
2.shmat()函数,在第一次创建共享内存的时候,它不能被任何进程访问,要想启动共享内存,就必须要连接到一个进程的地址空间。
3.shmdt()函数用来将共享内存从当前区域分离出来。
4.shmctl()函数是共享内存的控制函数

下面来看一个完整的基于共享内存的服务器/客户端的例子。在这个例子中。客户端负责创建一个共享区域,并且对里面的数据进行输出显示。在服务器端负责对共享区域进行数据的写入。

#ifndef SHM_COM_H
#define SHM_COM_H


#define TEXT_SZ 2048  //最大的文本大小

struct shared_use_st{
    int written_by_you; //控制标记
    char some_text[TEXT_SZ];  //文本缓冲区
};



#endif // SHM_COM_H

客户端:

#include <iostream>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/shm.h>
#include "shm_com.h"
using namespace std;

struct shared_use_st;

int main()
{
    //cout << "Hello World!" << endl;
    //第一个程序是消费者程序,在头文件之后,通过设置IPC_CREAT标志位的shmget调用来创建共享内存

    int running = 1;
    void* shared_memory = (void*)0;
    struct shared_use_st *shared_stuff;
    int shmid;
    srand((unsigned int )getpid());


    //创建一个共享内存
    shmid = shmget((key_t)1234 , sizeof(struct shared_use_st) , 0666| IPC_CREAT );

    if(shmid == -1){
        fprintf(stderr , "shmget failed!\n");
        exit(EXIT_FAILURE);

    }

    //现在让程序访问呢这个共享内存
    shared_memory = shmat(shmid , (void*)0 , 0);
    if(shared_memory == (void*)-1){
        fprintf(stderr , "shmat failed!\n");
        exit(EXIT_FAILURE);
    }

    printf("Memory attched at %X \n" , *(int*)shared_memory);


    //程序的下一部分将shared_memory分配给shared_stuff, 然后输出written_by_you中的文本。循环一直执行到哦啊written_by_you中end字符为止。sleep调用强博消费者程序在临界区多呆一会,让生产者程序等待.
    shared_stuff = (struct shared_use_st*)shared_memory;
    shared_stuff->written_by_you = 0;
    while(running){
        if(shared_stuff->written_by_you){
            printf("You wrote:%s " , shared_stuff->some_text);
            sleep(rand()%4);
            shared_stuff->written_by_you =  0;
            //如果字符中出现end字符,退出循环
            if(strncmp(shared_stuff->some_text , "end" , 3) == 0){
                running = 0;
            }

        }

    }


    //最后,分离共享内存,然后被删除.

    if(shmdt(shared_memory) == -1){

        fprintf(stderr , "shmdt failed!\n");
        exit(EXIT_FAILURE);
    }

    if(shmctl(shmid , IPC_RMID , 0) == -1){

        fprintf(stderr , "shmctl(IPC_RMID) failed!\n");
        exit(EXIT_FAILURE);

    }

   exit(EXIT_SUCCESS);


 //   return 0;
}

服务器端:

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

#include<sys/shm.h>
#include"shm_com.h"

int main()
{

    int running = 1;
    void* shared_memory = (void*)0;
    struct shared_use_st *shared_stuff;
    char buffer[BUFSIZ];
    int shmid;

    shmid = shmget((key_t)1234  , sizeof(struct shared_use_st) , 0666|IPC_CREAT);

    if(shmid == -1){
        fprintf(stderr , "shmget failed!\n");
        exit(EXIT_FAILURE);
    }

    shared_memory = shmat(shmid , (void*)0 , 0 );
    if(shared_memory == (void*)-1){
        fprintf(stderr , "shmat failed!\n");
        exit(EXIT_FAILURE);

    }


    printf("Memory attched ad %X\n" , *(int*)shared_memory);

    shared_stuff = (struct shared_use_st*)shared_memory;
    while(running){
        while(shared_stuff->written_by_you == 1){
            sleep(1);
            printf("waiting for client....\n");
        }


        printf("ENter some text...:");
        fgets(buffer , BUFSIZ  , stdin);

        strncpy(shared_stuff->some_text , buffer , TEXT_SZ);
        shared_stuff->written_by_you = 1;

        if(strncmp(buffer , "end"  , 3) == 0){

            running = 0;
        }
    }
    if(shmdt(shared_memory) == -1){
        fprintf(stderr , "shmdt failed !\n");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);

}

在上面代码就完成了对程序的实现。
下面就是在命令行中挂起客户端和运行服务器端的命令啦

./client &
./server

就可以实现数据在共享内存中的交互啦,很简单吧。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:178712次
    • 积分:4156
    • 等级:
    • 排名:第7425名
    • 原创:246篇
    • 转载:14篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论