利用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 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进 ...
随机推荐
- FC8下备份linux系统
linux系统可以使用tar来备份.<br><br> 我在FC8上装好了totem, mplayer, audacious, 并搞定了wifi后,我觉得该备份一下FC8系统.& ...
- Android Context作用
Context 用于访问全局信息的接口 App的资源: strings, drawable资源等等 工程代码:LearnContext.zip ---------------------------- ...
- 那些年被我坑过的Python——牵一发动全身 第十一章MySQL、ORM
#!/usr/bin/env python # -*- coding:utf-8 -*- __Author__ = "Zhang Xuyao" from sqlalchemy im ...
- 下载jdk-api 1.7文档
第一步:查看你所下载的JDK版本.在cmd中输入“java -version”即可. 第二步:输入网址:http://www.oracle.com/technetwork/index.html 第三步 ...
- iOS判断手机中是否 有 SIM卡---备用
[CTSIMSupportGetSIMStatus() isEqualToString:kCTSIMSupportSIMStatusNotInserted]可以判断是否插入了sim卡. 前提是把下面的 ...
- C#后台找不到前台html标签
没关系! 只要他在form表单里 , 咱在标签加上一个 runat="server"就可以在后台cs代码里找到他了
- Eclipse中查找接口实现类快捷键
就是点击某个接口某个方法名字的时候,直接跳到它的某个实现类里面,一般我们习惯对着那个接口的方法按F3,但是这会直接跳到接口类的源码中,那么呵呵,我们换一个ctrl+T 然后自己选择一下实现类就进去了. ...
- Unity3d 项目管理
Unity3d 项目管理 1.项目管理采用TortoiseSVN方式进行管理,但是也要结合人员管理的方式,尽量在U3D中多采用Scene(关卡的方式),以一下目录的方式进行管理! 以名字的方式进行合 ...
- 温习H3C S5500的VLAN配置
这,才是我想要的... ACCESS还是TRUNK TYPE?
- LXC是如何与CGROUP,namespace扯上关系的?再加上DOCKER.IO。完美!!!
最后还余下网络去攻克了. 不同的模板,只是在同一个LINUX内核上去实现不同的发行版的特性. 终归,都是用同样的内核来实现调度.故而是一个轻量极的方案. 而不像KVM一样,GUEST OS里的CPU也 ...