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=shmget(key, size, IPC_CREAT | IPC_EXCL | 0666)生成共享内存。
int shmid=shmget(key, 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>