共享內存是進程之間通信最快的方式。client將圖像數據讀入共享內存,server從共享內存中讀取數據。採用共享內存中的一個字符作爲標誌位實現共享內存的同步。
server.c
// server:讀取共享內存圖像數據
#include "comm.h"
static int SHMID = 0;
static unsigned char *ADDR = NULL;
void main()
{
int iLoop = 5;
int date = 0;
FILE *img = NULL;
// 初始化共享內存
SHMID = CreateShm(4096+1);
if(SHMID==-1)
{
printf("create share memory failed!\n");
exit(1);
}
ADDR = shmat(SHMID, NULL, 0);
printf("init server share memory succeed, shmid = %d\n", SHMID);
while((img = fopen("/home/fxhui/IPC/ipc_pv_img/new.jpg", "wb")) == NULL && iLoop)
{
printf("open file failed!, [%d]\n", iLoop);
iLoop--;
sleep(1);
}
// 信號同步
int semid;
int b = 0;
if((semid = initsem(0x200)) < 0)
{
printf("server init sem error!\n");
exit(1);
}
int fwriteSize = 0;
while(1)
{
if(ADDR[4096] == 'b')
{
fwriteSize = fwrite(ADDR, 1, 4096, img);
ADDR[4096] = 'a';
printf("fwriteSize = %d\n", fwriteSize);
}
if(ADDR[4096] == 'c')
{
fwriteSize = fwrite(ADDR, 1, 731, img);
printf("fwriteSize = %d\n", fwriteSize);
break;
}
}
/* 方式二
while(1)
{
if(ADDR[4096] == 'b')
{
b = atoi(ADDR);
printf("recv data = [%d]\n", b);
fputc(b, img);
ADDR[4095] = 'a';
}
if(ADDR[4096] == 'c')
break;
}
*/
fclose(img);
shmdt(ADDR);
DestroyShm(SHMID); // 銷燬IPC
}
client.c
// client:寫入共享內存圖像數據
#include "comm.h"
static int SHMID = 0;
static unsigned char *ADDR = NULL;
int main()
{
// 獲取共享內存
int iLoop = 5;
SHMID = GetShm(4096+1); // 獲取IPC鍵值:申請4096+1個字節的內存
ADDR = shmat(SHMID, NULL, 0); // 共享內存映射到進程頁表
printf("client init share memory succeed, SHMID = %d\n", SHMID);
// 準備傳送的數據
FILE *img;
char path[100] = { 0 };
snprintf(path, 100, "%s", "/home/fxhui/IPC/ipc_pv_img/LF.jpg");
while((img = fopen(path, "rb")) == NULL && iLoop)
{
printf("open file failed!, [%d]\n", iLoop);
iLoop--;
sleep(1);
}
fseek(img, 0, SEEK_END);
int len = ftell(img);
int m = len / 4096;
int n = len % 4096;
fseek(img, 0, SEEK_SET);
printf("%d %d \n", m ,n);
// 信號同步
int semid;
if((semid=initsem(0x200)) < 0)
{
printf("server init sem error!\n");
exit(1);
}
unsigned char *buffer;
int freadSize = 0;
buffer = (unsigned char *)malloc(sizeof(unsigned char)*4096);
ADDR[4096] = 'a';
while(1)
{
if(ADDR[4096] == 'a' && m--)
{
freadSize = fread(ADDR, 1, 4096, img);
ADDR[4096] = 'b';
printf("m = %d, freadSize = %d\n", m, freadSize);
}
if(m == 0)
{
sleep(1);
ADDR[4096] = 'c';
freadSize = fread(ADDR, 1, n, img);
printf("m = %d, freadSize = %d\n", m, freadSize);
printf("圖像讀取完畢!\n");
break;
}
}
/* int c = 0;
ADDR[4095] = 'a';
while(1)
{
if(ADDR[4095] == 'a')
{
if((c=fgetc(img))!= EOF)
{
printf("read date : [%d]\n",c);
sprintf(ADDR,"%d",c);
ADDR[4095] = 'b';
}
else
{
ADDR[4095] = 'c';
printf("圖像讀取完畢!\n");
break;
}
}
}
*/
free(buffer);
sleep(1);
fclose(img);
shmdt(ADDR);
return 0;
}
使用兩種方式實現數據的操作:fgetc讀取一個字節的數據和fread讀取一塊數據,兩種方式。
值得注意的是,使用了ADDR[4096]實現server和client的同步。
全部代碼:https://download.csdn.net/download/fengxianghui01/12302586