linux 共享内存 消息队列 udp通信

 

1.开辟共享内存

为了方便处理共享内存,把每一块共享内存都放入一个结构体中。

结构体定义在/dlp/cm/src/inc/com/CM_msinit.h文件中:

struct shm{

       char tname[20];   //共享内存名字

       u_long addr;      //共享内存地址

       u_long size;       //共享内存大小

       int opt;           //共享内存key

};

这个结构体对应于/env/CM_memory.ini文件中的内容:

CM_TBL      0x000000080000000   0x0004b14de0           2

 

程序执行时,首先读取/env/CM_memory.ini文件中的内容。然后,根据所需的共享内存名字在文件中搜索相应的纪录,得到纪录的索引号。如果没有索引号,就报错。

本处理函数为/dlp/cm/src/lib/src/com/CM_msinit.c文件中的int FIshminfo( char *file, char *name, int flag )函数。参数file就是CM_memory.ini文件;name就是共享内存名字;flag固定为0

 

其次,根据实际所需的内存大小,与/env/CM_memory.ini文件中的与该索引号相应的共享内存大小比较。如果文件中的大小小于实际所需的大小,报错。

 

第三步,调用int shmid=shmget(共享内存key, 共享内存大小, IPC_CREAT | IPC_EXCL | 0666)生成共享内存。本处理函数为/dlp/cm/src/lib/src/com/CM_msinit.c文件中的int FIsmemgt( char *name )函数。参数为对应于索引号的纪录数据。

shmget头文件:#include<sys/ipc.h>

               #include<sys/shm.h>

int shmid=shmgetkey, size, IPC_CREAT | IPC_EXCL | 0666)生成共享内存。

int shmid=shmgetkey, size, 0666取得根据key已经生成的共享内存。

 

第四步,调用static u_long w_addr = (u_long)shmat( shmid, (char *)共享内存地址, 0 ) 得到共享内存的地址。Struct TS_ssptt  * tbl_pt=(struct TS_ssptt *)( char * ) w_addr

本处理函数为/dlp/cm/src/lib/src/com/CM_msinit.c文件中的char*FSPsmemat( char *name )函数。参数为对应于索引号的纪录数据。

Shmat头文件:#include<sys/types.h>

               #include<sys/shm.h>

 

第五步,从各个配置文件中,将数据读入共享内存中相应的结构体中。

第六步,删除共享内存   shmctl(shmid,IPC_RMID,NULL);

2.Message送收信

为了方便,也定义一个结构体。/dlp/cm/src/inc/tbl/CM_Tsque.h

主要有以下几个字段:

Struct  TS_squet1 {

Int  squet_msgkey;  /*key*/

       Int  squet_qid;       /*消息ID */

       u_short  squet_msgtype;   /*消息类型*/

       u_short  squet_getflg;      /*消息ID有无标志 0 1 */

       u_char   squet_prcid[4];  /*进程略称 "nnnn"  */

       u_char   squet_prcname[50]; /*进程名称 */

       u_int      squet_pssid;  /* 自消息ID  */

       。。。。。。

 

第一步,key=ftok(“.”,’a’); 只要服务器和客户端执行目录一样。就可以这么用。A可以是任意字符。得到唯一的key或者直接指定一个key。方法如下:

wk_buff字符串数组的内容是0x1234,作为指定的key

/data/real/cons/ CM_FILSque文件中读取key

Long henkan;

sscanf(&wk_buff[2],"%x",&henkan);

写入结构体:squet_msgkey = ( long )henkan ;

squet_getflg = 0 ;

方法详见/dlp/cm/src/ZINI/CMSTZINIT2.c文件中CSTBTquetnkai()函数。

ftok头文件:#include<sys/types.h>

            #include<sys/ipc.h>

 

第二步,根据第一步读取的key,生成消息ID

方法详见/dlp/cm/src/lib/src/com/CM_quemsg.c文件中的int FIzmget( pid )函数。

squet_qid = msgget(squet_msgkey, IPC_CREAT | IPC_EXCL | 0666);得到squet_qid,消息就是通过squet_qid进行发送和接收的。为了使用方便,可以将消息ID和进程名称对应起来,写入结构体squet_prcid

squet_getflg = 1 ;

msgget头文件:#include<sys/types.h>

               #include<sys/ipc.h>

               #include<sys/msg.h>

 

第三步,msgsnd(qid,qbuf,length,0);

Qid是目的进程的。

msgsnd头文件:#include<sys/types.h>

               #include<sys/ipc.h>

               #include<sys/msg.h>

 

第四步,msgrcv(qid,qbuf,length,type,0);

Qid是自进程的。

msgrcv头文件:#include<sys/types.h>

               #include<sys/ipc.h>

               #include<sys/msg.h>

 

第五步,删除消息队列

        Msgctl(qid,IPC_RMID,NULL);

      

 

3.UDP通信

为了方便,也定义一个结构体。/dlp/cm/src/inc/tbl/CM_Tslin.h

主要有以下几个字段:

Struct  TS_slint2 {

u_short  slint_lineno; /*回线号*/

u_short  slint_portno; /*端口号*/

int          slint_socketid; /*socket ID*/

u_short  slint_bportno; /*broadcast端口号*/

u_int      slint_ipadr; /*IP 地址*/

u_int      slint_brdadr; /*广播地址*/

。。。。。。

第一步,socket生成。

slint_socketid = socket(PF_INET,SOCK_DGRAM,0);

socket头文件:#include<sys/types.h>

               #include<sys/socket.h>

 

第二步,本机端口开放

struct     sockaddr_in  svconnaddr;

svconnaddr.sin_family=PF_INET;

svconnaddr.sin_port=htons(slint_portno); /*本机开放的端口*/

svconnaddr.sin_addr.s_addr=htonl(INADDR_ANY);/*本机IP*/

htons, htonl头文件:#include<netinet/in.h>

 

第三步,设置socket状态。

Int opt=1;

setsockopt(slint_socketid,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(int));

第四步,绑定

bind(slint_socketid,(struct sockaddr *)&svconnaddr,sizeof(svconnaddr));

sendto,recvfrom,bind头文件:#include<sys/socket.h>

               #include<sys/types.h>

 

通过以上4步,打开了本机端口,其他机器就可以通过IP和端口进行UDP通信。

第五步,送信

1.送给指定IP地址

struct     sockaddr_in  to;

to.sin_family=PF_INET;

to.sin_port=htons(slint_portno);/*目标机端口*/

to.sin_addr.s_addr= slint_ipadr;/*目标机IP*/

sendto(slint_socketid,&sendbuff[0],sleng,0,(struct sockaddr *)&to,sizeof(to));

2.广播

struct     sockaddr_in  to;

to.sin_family=PF_INET;

to.sin_port=htons(slint_portno);/*目标机端口*/

to.sin_addr.s_addr= inet_addr("192.168.1.255");/*目标机IP*/

sendto(slint_socketid,&sendbuff[0],sleng,0,(struct sockaddr *)&to,sizeof(to));

inet_addr头文件:#include<sys/socket.h>

               #include<netinet/in.h>

               #include<arpa/inet.h>

 

第六步,收信

recvfrom(slint_socketid,data,MAX_SOCK,0,(struct sockaddr *)&from,&len);

注意这里的from。如果是225的机器送给226的,那么,226收到信后,打印

fprintf(stdout,"I have received from %s/n",inet_ntoa(from_addr.sin_addr));

输出:I have received from 192.168.1.226

 

取得网络数据的头文件:#include<netdb.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值