管道通信初级

1. pipe管道通信,其实socket也要依赖于它,可以实现双向通信。还能解决并发。
比共享内存和邮槽都靠谱。
2. 禁止一个程序打开多次,也就是锁定一个程序只能打开一次,限制它的打开次数,用管道就    必须这么做,否则会发生冲突。
3.有线程池也有管道池

4.例子

  • 服务端
#include <stdio.h>
#include <Windows.h>

//管道是存在于操作系统
#define SIZE 4096
char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用这种模式命名等同于设备。
HANDLE m_pipe = NULL;    //管道的句柄

//创建一个管道
void start()
{
    m_pipe = CreateNamedPipeA(
        pipename,    //管道名称
        PIPE_ACCESS_DUPLEX,    //管道的读写属性
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,        //消息模式,读模式,等待模式(相当于阻塞模式)PIPE_TYPE_MESSAGE一般情况有两种,用的最多的是消息模式,另一种是二进制模式(BYTE模式)。
        PIPE_UNLIMITED_INSTANCES,//同时开启管道的最大个数,最多是255,在服务器上可以开辟更多。
        SIZE,    //输出(读)的缓冲区大小
        SIZE,    //输出(写)的缓冲区大小
        0,    //客户端超时时间
        NULL
        );

        if (m_pipe == NULL)
        {
            printf("创建失败");
            return;
        }

        //连接这个管道并且判断是否连上。
        BOOL isconnect = ConnectNamedPipe(m_pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
        if (isconnect)
        {
            MessageBoxA(0, "connected OK", "connected OK", 0);
        }
        else
        {
            printf("创建失败。");
        }
}

void read()
{
    char buf[SIZE] = { 0 };        //我们有可能把管道的所有信息都读了,初始化时原则上初始为0。
    int last = 0;
    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是纯C语言里边,如果是C的管道库,用Readpipe,C语言把所有的设备当成文件来处理,所以用ReadFile,若返回值是0表示读取失败.
    {
        printf("读取失败");
        return;
    }
    printf("\nread%s", buf);
}

void write()
{
    char str[128] = "举头望明月,这就是管道。";
        int last = 0;
        BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);
        if (!res)
        {
            printf("写入失败");
        }
}
void test()
{
    //先尝试能不能打开,打开了,就说明原来存在。如果没有打开就创建一个。
    HANDLE mutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "guandaoserver"); //把guandaoserver去掉就是匿名,就不能跨进程了。
        if (mutex == NULL)
        {//创建
            mutex = CreateMutexA(NULL, TRUE, "guandaoserver"); //如果是匿名就不能发挥作用了
        }
        else
        {
            MessageBoxA(0, "only one", "only one", 0);
            exit(0); //exit(0)表示正常退出,exit(x)都表示异常退出.
        }
}
//mutex是内核所有的进程都能读到,限定程序只能打开一次。
void main()
{
    test();
    start();
    printf("服务器启动\n");
    system("pause");
    write();
    system("pause");
    read();
    system("pause");
}
  • 客户端
#include <stdio.h>
#include <Windows.h>

#define SIZE 4096
char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用这种模式命名等同于设备。
HANDLE m_pipe = NULL;    //管道的句柄

void read()
{
    char buf[SIZE] = { 0 };        //我们有可能把管道的所有信息都读了,初始化时原则上初始为0。
    int last = 0;
    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是纯C语言里边,如果是C的管道库,用Readpipe,C语言把所有的设备当成文件来处理,所以用ReadFile,若返回值是0表示读取失败.
    {
        printf("读取失败");
        return;
    }
    printf("\nread%s", buf);
}

void write()
{
    char str[128] = "又丑又傻多看书。";
    int last = 0;
    BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);
    if (!res)
    {
        printf("写入失败");
    }
}

void main()
{
    //NMPWAIT_WAIT_FOREVER 常用到无限等待,表示如果没有管道就一直卡着
    if (!WaitNamedPipeA(pipename, NMPWAIT_USE_DEFAULT_WAIT))
        //NMPWAIT_USE_DEFAULT_WAIT表示一般等待,只等一下
    {
        MessageBoxA(0, "connected NO", "connected NO", 0);
        return;
    }

    m_pipe = CreateFileA(pipename, //名称
        GENERIC_WRITE | GENERIC_READ, //既能读又能写,是通过位运算符实现的。
        1, //表示是否共享
        NULL, //默认安全属性
        OPEN_EXISTING, //打开已经存在的
        FILE_ATTRIBUTE_NORMAL,//这两个表示两个默认的属性
        NULL
        );

    system("pause");
    read();
    system("pause");
    write();
    system("pause");

}
时间: 2024-07-30 20:32:21

管道通信初级的相关文章

管道通信

管道大致分为两种: 1.匿名管道:这个一般只能用于父进程创建管道传递给子进程,可以父子进程通信 2.有名管道:这种管道存在于文件系统中,所以任意进程都能找到,都可以通过它来通信 API: #include <unistd.h> int pipe(int fds[2]) fds[0] 是读取文件描述符,也就是管道出口 fds[1] 是写文件描述符,也就是管道入口 创建一个匿名管道 成功返回0,失败返回-1 int dup(int oldfd);创建文件描述符的副本 int dup2(int ol

C#命名管道通信

原文:C#命名管道通信 C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通信来做消息通信. 管道通信以前在大学学过,包括匿名管道和命名管道.匿名管道只能用在父子进程之间:命名管道可以用在两个进程甚至跨服务器通信.这里给出命名管道的示例. 服务器端代码 private static void WaitData() { using (NamedPipe

管道通信之无名管道---pipe()

pipe()函数在子进程产生之前就应该存在. 父子进程之间只进行一次传递 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:onepipe.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #inclu

管道通信,王明学learn

管道通信 一.通讯目的 1.数据传输 一个进程需要将数据发送给另一个进程. 2.资源共享 多个进程之间共享同样的资源. 3.通知事件 一个进程需要向另一个/组进程发送消息,通知它们发生了某事件. 4.进程控制 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变. 二.通讯发展 Linux进程间通信(IPC:interprocesscommunication)由以下几部分发展而来: 1.UNIX进程间通信 2.基于Sy

PHP多进程编程(2):管道通信

一个进程如果是个人英雄主义,那么多进程就是集体主义.(不严格区分多进程 和 多线程的差别) 你不再是一个独行侠,而是一个指挥家. 独来独往,非常自由自在,但是,很多时候,不如众人拾柴火焰高. 这就是我对多进程的理解.多线程编程的主要问题是:通信 和 同步问题. 更多PHP 多线程编程的背景知识见: PHP多进程编程(一) 在PHP 中,如果光用pcntl ,实现比较简单的通信问题都是很困难的. 下面介绍管道通信: 1. 管道可以认为是一个队列,不同的线程都可以往里面写东西,也都可以从里面读东西.

python Subprocess执行系统命令管道、读取结果【多进程,进程间管道通信】

# -*- coding:utf-8 -*- __author__ = 'magicpwn' import subprocess import sys reload(sys) sys.setdefaultencoding('utf-8') # 执行命令的两个函数,新建进程执行系统命令 s = subprocess.check_call('dir', shell=True) p = subprocess.call('dir', shell=True) print s, p # 执行命令并捕获系统命

Linux学习记录--命名管道通信

命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中. 这样,即使与FIFO的创建进程不存在亲缘关系的进程,仅仅要可以訪问该路径,就行彼此通过FIFO相互通信 有名管道创建 int mkfifo(const char * pathname, mode_t mode)

进程间管道通信

父子进程间通过管道通信. 管道只能在具有公共祖先的两个进程间使用,通常,一个管道有另一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了. 一般的进程,fd[0]表示读,fd[1]表示写. 如果有用到管道,则写进管道,从管道读. 父子进程之间. 所以,通过简单的read ,write函数,把目标文件设为fd[0] fd[1]即可以完成父子进程间的通信. write用法,read类似.   int write(int handle, void *buf, int nbyte

Windows上的多线程管道通信

一个管道实际上就是一块共享内存,它有两端,分别用于两个进程的读写.这里介绍下如何在Windows上实现线程之间的管道通信. 参考原文:Multithreaded Pipe Communication on Windows C#多线程管道通信 创建一个管道实例: IntPtr pipe = PipeCommunication.Pipe.CreateNamedPipe(                 PIPE_NAME,                  (uint)PipeCommunicati