利用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 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进 ...
随机推荐
- extjs下拉框添加复选框
给ComboBox组件配置listConfig 下拉框代码: var gyslxcm = Ext.create('Ext.form.field.ComboBox',{ id : 'gyslxcm', ...
- C# .NET3.5 改为 到.NET2.0 时 TypedTableBase 报错解决方法
NET 3.5 降版本 到.NET 2.0.不出意外,问题必然来了.编译错误一:错误 1 命名空间“System”中不存在类型或命名空间名称“Linq”(是缺少程序集引用吗?)解决:删掉该引用--没用 ...
- QTP10破解
1. 下载QTP10.0版本 http://h30302.www3.hp.com/prdownloads/T6510-15063.zip?ordernumber=380454070&itemi ...
- phpcms v9 get调用标签整理
常见的phpcms标签调用 1.调用本系统单条数据(调用ID为1的信息,标题长度不超过25个汉字,显示更新日期): "select * from phpcms_content where ...
- linux下svn客户端报错Cannot negotiate authentication mechanism的解决方法
svn客户端报错Cannot negotiate authentication mechanism的解决方法: 问题出现的原因之一: 因为SVN服务器配置了saslauthd服务用来实现与ldap的对 ...
- python中对文件、文件夹的操作需要涉及到os模块和shutil模块。
创建文件:1) os.mknod("test.txt") 创建空文件2) open("test.txt",w) 直接打开一个文件,如果文件不存在则创建文件 创建 ...
- 使用模版引擎填充重复dom元素
引入arttemplate,定义newajax发送跨域请求获得数据,将获得的数据用定义的格式渲染 <!DOCTYPE html><html lang="en"&g ...
- js 实现 di
前些时候有使用过AngularJS一些时间,最大的感受就是Angular完全颠覆了我们开发Web应用的方式,自己被其许多耳目一新的设计思想所折服. 首先想说的就是依赖注入(DI),这也意味着,你在使用 ...
- iso 开发学习--简易音乐播放器(基于iPhone4s屏幕尺寸)
三个按钮 一个进度条 贴图(软件中部分图片,来自网络,如果侵犯了您的权益,请联系我,会立刻撤下) 核心代码 // // ViewController.m // 08-10-MusicPlayer / ...
- The Suspects(简单的并查集)
Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, wa ...