进程AB通过命名管道通信

要实现进程A和进程B之间的双向通信,并通过命名管道(FIFO)实现定时消息发送和CRC校验,可以使用以下步骤和代码示例。

进程A(发送消息并接收CRC校验结果)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <time.h>

#define FIFO_PATH_A "/tmp/myfifoA"
#define FIFO_PATH_B "/tmp/myfifoB"

uint32_t crc32(const void *data, size_t length) {
    // CRC-32 implementation (simplified for demonstration)
    // You can use a more optimized version or library.
    static const uint32_t table[256] = { /* Precomputed CRC table */ };
    uint32_t crc = 0xFFFFFFFF;
    const uint8_t *byte = data;
    while (length--) {
        crc = table[(crc ^ *byte++) & 0xFF] ^ (crc >> 8);
    }
    return crc ^ 0xFFFFFFFF;
}

int main() {
    int fdA, fdB;
    const char *message = "Hello from Program A";
    char buffer[100];
    uint32_t crc;

    // Create FIFOs if they do not exist
    if (mkfifo(FIFO_PATH_A, 0666) == -1 && errno != EEXIST) {
        perror("mkfifo A");
        exit(EXIT_FAILURE);
    }
    if (mkfifo(FIFO_PATH_B, 0666) == -1 && errno != EEXIST) {
        perror("mkfifo B");
        exit(EXIT_FAILURE);
    }

    // Open FIFOs
    fdA = open(FIFO_PATH_A, O_WRONLY);
    if (fdA == -1) {
        perror("open A");
        exit(EXIT_FAILURE);
    }
    fdB = open(FIFO_PATH_B, O_RDONLY);
    if (fdB == -1) {
        perror("open B");
        exit(EXIT_FAILURE);
    }

    while (1) {
        // Send message
        write(fdA, message, strlen(message) + 1);
        
        // Compute CRC of the message
        crc = crc32(message, strlen(message));
        printf("Sent message: %s\n", message);

        // Wait for CRC check result
        read(fdB, buffer, sizeof(buffer));
        printf("Received CRC: %s\n", buffer);

        // Sleep for n seconds
        sleep(5); // Change 5 to the desired interval
    }

    // Clean up
    close(fdA);
    close(fdB);
    unlink(FIFO_PATH_A);
    unlink(FIFO_PATH_B);

    return 0;
}

进程B(接收消息并发送CRC校验结果)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

#define FIFO_PATH_A "/tmp/myfifoA"
#define FIFO_PATH_B "/tmp/myfifoB"

uint32_t crc32(const void *data, size_t length) {
    // CRC-32 implementation (simplified for demonstration)
    // You can use a more optimized version or library.
    static const uint32_t table[256] = { /* Precomputed CRC table */ };
    uint32_t crc = 0xFFFFFFFF;
    const uint8_t *byte = data;
    while (length--) {
        crc = table[(crc ^ *byte++) & 0xFF] ^ (crc >> 8);
    }
    return crc ^ 0xFFFFFFFF;
}

int main() {
    int fdA, fdB;
    char buffer[100];
    uint32_t crc;
    char crc_result[100];

    // Create FIFOs if they do not exist
    if (mkfifo(FIFO_PATH_A, 0666) == -1 && errno != EEXIST) {
        perror("mkfifo A");
        exit(EXIT_FAILURE);
    }
    if (mkfifo(FIFO_PATH_B, 0666) == -1 && errno != EEXIST) {
        perror("mkfifo B");
        exit(EXIT_FAILURE);
    }

    // Open FIFOs
    fdA = open(FIFO_PATH_A, O_RDONLY);
    if (fdA == -1) {
        perror("open A");
        exit(EXIT_FAILURE);
    }
    fdB = open(FIFO_PATH_B, O_WRONLY);
    if (fdB == -1) {
        perror("open B");
        exit(EXIT_FAILURE);
    }

    while (1) {
        // Read message
        read(fdA, buffer, sizeof(buffer));
        printf("Received message: %s\n", buffer);

        // Compute CRC of the message
        crc = crc32(buffer, strlen(buffer));
        sprintf(crc_result, "%u", crc);

        // Send CRC result
        write(fdB, crc_result, strlen(crc_result) + 1);
    }

    // Clean up
    close(fdA);
    close(fdB);
    unlink(FIFO_PATH_A);
    unlink(FIFO_PATH_B);

    return 0;
}

使用步骤

  1. 编译两个程序:gcc -o progA progA.cgcc -o progB progB.c
  2. 运行进程B(接收和处理消息):./progB
  3. 运行进程A(发送消息):./progA

这将实现进程A每隔n秒发送消息,并从进程B接收CRC校验结果。

#makefile文件

创建一个通用的 Makefile 以支持 proc_Aproc_B 两个源文件,并尽可能减少修改的工作量,可以按照以下步骤进行:

示例 Makefile

# 定义变量
CC = gcc
CFLAGS = -Wall -g
TARGETS = proc_A proc_B
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

# 默认目标
all: $(TARGETS)

# 目标规则
proc_A: proc_A.o
	$(CC) -o $@ $^ $(CFLAGS)

proc_B: proc_B.o
	$(CC) -o $@ $^ $(CFLAGS)

# 生成 .o 文件
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# 清理
clean:
	rm -f $(TARGETS) $(OBJECTS)

# 伪目标
.PHONY: all clean

说明

  • CC:指定使用的编译器,这里是 gcc
  • CFLAGS:编译选项,-Wall 启用所有警告,-g 生成调试信息。
  • TARGETS:最终要生成的可执行文件,这里是 proc_Aproc_B
  • SOURCES:当前目录下所有的 .c 源文件。
  • OBJECTS:所有的 .o 对象文件,这些文件由 .c 文件生成。
目标规则
  • proc_Aproc_B 目标规则中,$@ 代表目标文件名(例如 proc_A),$^ 代表所有依赖的文件(例如 proc_A.o)。
生成 .o 文件
  • %.o: %.c 规则表示每个 .c 文件如何生成对应的 .o 文件。
清理
  • clean 目标用于删除生成的可执行文件和对象文件。
伪目标
  • .PHONY 声明了 allclean 为伪目标,这样即使有同名文件也不会影响 make 的行为。

使用方法

  1. 编译所有目标:运行 make。这会生成 proc_Aproc_B 可执行文件。
  2. 清理生成的文件:运行 make clean

扩展和修改

如果以后需要更改源文件名或添加新源文件,只需将新的源文件放在当前目录中,Makefile 会自动检测并处理它们,无需修改 Makefile 本身。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值