引自:《Unix环境下利用Socket和消息队列构建应用通信平台》
《基于消息队列软总线的系统集成与数据交换方案》
/*server.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <svs/socketvar.h> #include <netdb.h> #include <netinet/in.h> #include <sys/ipc.h> #include <sys/msg.h> #define SOIN 1600 #define S00UT 160l #define SPORT 2000 #define MSGTYPE lOO struct data { long msgtype; char buff[20]; } int main() { struct data mesgin, mesgout; struct hostent *host; struct sockaddr_in sn; struct sockaddr sk; int len = sizeof(sk); int qin, qou, sd, conn, flag, count, qcount; char name[15],buf[20] /*创建消息队列*/ if((qin = msgget(SQIN,IPC_CREAT | 0660)) == -1) { perror("qin emr!"); exit(1); } if((qou = msgget(SQOUT, IPC_CREAT | 0660)) == -1) { perror("qou error!"); exit(1); } /*获取本地主机名*/ flag = gethostmme(name, sizeof(name)); if(flag == -1) { perror("gethostname error!"); exit(1); } /*根据主机名获取本地主机地址*/ if((host = gethostbyname(name)) == NULL) { perror("gethosthyname error!"); exit(1); } bzero((char *)&sn, sizeof(sn)); /*设定使用的地址族*/ sn.sinfamily=AFJNET; /*将端口号本地字节序转换为网络字节序*/ sn.sin_port=htons(SPORT); bcopy(host->h_addr, (char*)&sn.sin_addr, host->h_length); /*创建Socket. PF_INET表示使用TCP/IP协议族*/ /*socket_STREAM指明使用流服务类型,即使用TCP协议*/ if((sd = socket(PF_INET, SOCKjTREAM, 0))== -1) { close(sd); perror(”socket error!”); exit(1); } /*指明本地端点地址,包含IP地址和协议端口号, 服务器将在知名端口号等待连接*/ if(bind(sd, (stmct sockaddr *)&sn, sizeof(sn))) { close(sd); perror("bind error!"); exit(1); } /*本例中,客户端将独占连接,因此队列长度设为l*/ if(1isten(sd,1)) { perror("listen error!"); exit(1); } while(1) { /*accept为连接请求建立新的socket,返回其描述符,即可在 新的socket上传送数据*/ if((conn=accept(sd, &sk, &len)) == -1) { close(sd); perror("accept enw!"); exit(1); } for(;;) { /*从Socket接收数据*/ count=recv(conn, buf, 20, 0); if(count>O) { mesgin.msgtype = MSGTYPE; bcopy(buf, mesgin.buff, 20); qcount = msgsnd(qin, &mesgin, 20, 0); } /*客户端连接断开,便跳出循环体*/ else if(count==O) break; /*从队列读取消息*/ qcount = msgrcv(qou, &mesgout, 20, 0, 0); /*向Socket发送数据流*/ count=send(conn, mesgout.buf, 20, 0); } close(conn): } return 0; }
/*client.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <svs/socketvar.h> #include <netdb.h> #include <netinet/in.h> #include <sys/ipc.h> #include <sys/msg.h> #define SOIN 1600 #define S00UT 160l #define SPORT 2000 #define MSGTYPE lOO struct data { long msgtype; char buff[20]; } int main() { struct data mesgin, mesgout; struct hostent *host; struct sockaddr_in sn; struct sockaddr sk; int len = sizeof(sk); int qin, qou, sd, conn, flag, count, qcount; char name[15], buf[20]; /*创建消息队列*/ if((qin = msgget(SQIN, IPC_CREAT | 0660)) == -1) { perror("qin error!"); exit(1); } if((qou = msgget(SQOUT, IPC_CREAT | 0660)) == -1) { perror("qou error!"); exit(1); } /*获取本地主机名*/ flag = gethostmme(name, sizeof(name)); if(flag == -1) { perror("gethostname error!"); exit(1); } /*根据主机名获取本地主机地址*/ if((host = gethostbyname(name)) == NULL) { perror("gethosthyname error!"); exit(1); } bzero((char *)&sn, sizeof(sn)); /*设定使用的地址族*/ sn.sinfamily = AFJNET; /*将端口号本地字节序转换为网络字节序*/ sn.sin_port = htons(SPORT); bcopy(host->h_addr, (char*)&sn.sin_addr, host->h_length); /*创建Socket. PF_INET表示使用TCP/IP协议族*/ /*socket_STREAM指明使用流服务类型,即使用TCP协议*/ if((sd = socket(PF_INET, SOCKjTREAM, 0))== -1) { close(sd); perror("socket error!"); exit(1); } /*指明本地端点地址,包含IP地址和协议端口号, 服务器将在知名端口号等待连接*/ if(bind(sd, (stmct sockaddr *)&sn, sizeof(sn))) { close(sd); perror("bind error!"); exit(1); } /*本例中,客户端将独占连接,因此队列长度设为l*/ if(1isten(sd, 1)) { perror("listen error!"); exit(1); } while(1) { /*accept为连接请求建立新的socket,返回其描述符,即可在 新的socket上传送数据*/ if((conn = accept(sd, &sk, &len)) == -1) { close(sd); perror("accept enw!"); exit(1); } for(;;) { /*从Socket接收数据*/ count = recv(conn, buf, 20, 0); if(count>O) { mesgin.msgtype = MSGTYPE; bcopy(buf, mesgin.buff, 20); qcount = msgsnd(qin, &mesgin, 20, 0); } /*客户端连接断开,便跳出循环体*/ else if(count == O) break; /*从队列读取消息*/ qcount = msgrcv(qou, &mesgout, 20, 0, 0); /*向Socket发送数据流*/ count = send(conn, mesgout.buf, 20, 0); } close(conn); } return 0; }
/*dsp.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define SQIN 1600 #define SOOUT 160l #define MSGTYPE lOO struct data { long msgtype; char buff[20]; } int main() { int qin, qou, qcount; struct data mesg; struct msgid_ds msgbuf; FILE *fp; /*当关键字为sQIN或sQOuT的队列存在时,将返回其消息 队列描述符*/ if((qin = msgget(SQIN,IPC_CREAT | 0660)) == -1) { perror("qin emr!"); exit(1); } if((qou = msgrcv(qout, IPC_GREAT | 0660)) == -1) { perror("qou error!"); exit(1); } again: qcount = msgrcv(qin, &mesg, 20, 0, 0); /*将从客户端收到的模拟数据流写入文件*/ fp = fopen("stream.dat", "a.dat"); fprintf(fp, ”%s \n”, mesg.buff); fclose(fp); qcount = msgsnd(qou, &mesg, 20, 0); goto again; return 0; }
/*req.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #onclude <sys/msg.h> #define CQOUT 1400 #define MSGTYPE 100 struct data { long msgtype; char buff[20]; }; int main() { int dl, count; struct data msg; if((dl = megget(CQOUT,IPC_CREAT | 0666)) == -1) { perror("queue error!\n"); exit(1); } sprintf(msg.buff, "%s", "通信平台的模拟数据流"); msg.msgtype = MSGTYPE; count = msgsnd(dl, &msg, 20, 0); return 0; }
/*cdp.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define CQIN 1401 struct data { long msgtype; char buf[20]; }; int main() { int qin, qcount; struct data mesg; FILE *fp; if((qin = msgget(CQIN, IPC_CREAT | 0660))-1) { perror("qin error"); exit(1); } for( ; ; ) { qcount = msgrcv(qin, &mesg, 20, 0, 0); mesg.buff[20] = fp = fopen("stream.dat", "a+"); fprintf(fp, "%s\n", mesg.buf); fclose(fp); } return 0; }