利用System V消息队列实现回射客户/服务器
一、介绍
在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如:
1. 服务器必须启动之时,客户端才能连上服务端,并与服务端进行通信;
2. 利用套接口描述符进行通信,必须知道对端的IP与端口。
二、相关函数介绍
下面,我们利用System V消息队列来实现进程间的通信:
首先,我们先来了解一下下面几个函数:
1. msgget: 该函数用于打开或创建消息队列,其作用相当与文件操作函数open。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgget(key_t key, int msgflg);
2. msgsnd:消息发送函数
3. msgrcv:消息接收函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
4. struct msgbuf
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[]; /* message data */
};
mtype 消息类型
mtext 消息内容
三、实现原理
服务器端:只接收类型为1的消息,接收完毕之后,取出mtext的前四个字节并存储为client_pid,并将消息类型mtype修改为client_pid;
客户端:只发送类型为1的消息,即将 mtype 置为1,并将mtext的前四个字节的内容设为自身的进程id,即pid.
四、编程实现如下:
客户端:
/*************************************************************************
> File Name: echocli.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Tue 28 Oct 2014 11:25:48 AM HKT
************************************************************************/ #include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while()
#define MSGMAX 8192 struct msgbuf
{ long mtype; /* type of message */
char mtext[MSGMAX]; /* message text */
}; void echo_cli(int msgid)
{
int pid = getpid();
int n; struct msgbuf msg;
memset(&msg, , sizeof(msg));
msg.mtype = ;
*((int*)msg.mtext) = pid; while(fgets(msg.mtext + , MSGMAX, stdin) != NULL)
{
msg.mtype = ;
if(msgsnd(msgid, &msg, + strlen(msg.mtext + ), IPC_NOWAIT) < )
ERR_EXIT("msgsnd");
memset(msg.mtext + , , MSGMAX - );
if((n = msgrcv(msgid, &msg, MSGMAX, pid, )) < )
ERR_EXIT("msgrcv");
fputs(msg.mtext + , stdout);
memset(msg.mtext + , , MSGMAX - );
}
} int main(int argc, char **argv)
{
int msgid;
msgid = msgget(, );//open
if(msgid == -)
ERR_EXIT("msgget"); echo_cli(msgid);
return ;
}
服务端:
/*************************************************************************
> File Name: echosrv.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Tue 28 Oct 2014 11:25:58 AM HKT
************************************************************************/ #include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while() #define MSGMAX 8192 struct msgbuf
{
long mtype; /* type of message */
char mtext[MSGMAX]; /* message text */
}; void echo_srv(int msgid)
{
int n;
struct msgbuf msg;
memset(&msg, , sizeof(msg));
while()
{
//only recv the message of type = 1
if((n = msgrcv(msgid, &msg, MSGMAX, , )) < )
{
ERR_EXIT("msgrcv");
} fputs(msg.mtext + , stdout);
//client pid
int pid;
pid = *((int*)msg.mtext); //回射
msg.mtype = pid;//type
msgsnd(msgid, &msg, n, );
memset(&msg, , sizeof(msg));
}
} int main(int argc, char **argv)
{
int msgid;
msgid = msgget(, IPC_CREAT | );
if(msgid == -)
{
ERR_EXIT("msgget");
}
echo_srv(msgid);
return ;
}
存在问题:
1. 不同主机间不同的进程无法进行通信。
2. 消息的长度受到限制MSGMAX
3. 消息的数量收到限制MSGMNB
4. 会出现死锁问题。
利用System V消息队列实现回射客户/服务器的更多相关文章
- 用system v消息队列实现回射客户/服务器程序
客户端程序 #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include< ...
- 消息队列实现回射客户/服务器和 msgsnd、msgrcv 函数
一.msgsnd 和 msgrcv 函数 #include <sys/types.h> #include <sys/ipc.h> #include <sys/ms ...
- Linux IPC实践(6) --System V消息队列(3)
消息队列综合案例 消息队列实现回射客户/服务器 server进程接收时, 指定msgtyp为0, 从队首不断接收消息 server进程发送时, 将mtype指定为接收到的client进程的pid ...
- 第二十七章 system v消息队列(三)
消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...
- 进程间通信 System V 消息队列
1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...
- 第6章 System V消息队列
6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- UNIX环境高级编程——system V消息队列
unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消 ...
- linux c编程:System V消息队列一
消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进 ...
随机推荐
- 搜索所有的路径-矩阵运算-暴力-ACM
给定一个n*n整数矩阵,定义对I行的SHIFT操作( 0 <= i < n ),是将第I行所有元素都右移一位,最右边的移到最左边. 你可以对任意行进行任意次SHIFT操作,使得: max0 ...
- php里 \r\n换行问题
<?php echo "hello"; echo "\r\n"; echo "world"; ?> 在浏览器输出的是hello ...
- ubuntu install opengrok
总结: 1. 安装jdk和tomcat 2. 安装ctags 3. 解压opengrok.tar.gz包, 然后将source.war复制到tomcat/webapp下面 sudo cp -R ope ...
- 项目知识点.Part3
内存管理: 基本数据类型或者Core Foundation对象都没有引用计数 主线程会自动创建释放池,子线程需要手动创建释放池. 具体的区别:http://www.cnblogs.com/langti ...
- 关于win8.1“连接被远程计算机关闭”的一种解决方案
我就是连接的时候出现"连接被远程计算机关闭",然后想着可能是win8更新之后网络协议 出问题了,后来无意中发现e信在第一次启动的时候会在网络适配器中会多出很多网卡,其中三个是带感叹 ...
- while死循环问题-输入字符就会死循环
问题: 是否会遇到这样的问题,在while循环中 sanf("%d",&a);如果输入的不是数字,是字符就会进入死循环. 解决方案:都是缓冲区惹的祸,输入字符后,字符会一直 ...
- oracle 查询dblink的方法
oracle 查询dblink的方法: SYSDBA登录, sys登录 SELECT * FROM SYS.link$;
- IE8一枝独秀的JS兼容BUG
// 例如淡入淡出的封装类文件 function ImagesEff(div,time){ this.arr=[];//装载所有div this.time=time; this.recordOld=n ...
- 权重随机算法的java实现
一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果 ...
- SVN:分支合并到主干
合并日志: --- Merging r173674 through r175986 into '.': C src/test/java/com/test/rigel/sandbox/organizat ...