You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下NodeJS与C程序通信报错:打开Unix域套接字失败

Node.js与C程序Unix套接字通信问题排查与解决

问题场景

在Linux环境下尝试用Node.js搭建IPC服务端与C程序通信,但C程序和echo命令写入目标文件时均报错,尽管文件存在。

Node.js服务端代码

'use strict';

const net = require('net');
const pipename = '/tmp/pipe1';
const fs = require('fs');

let server = net.createServer(function(socket){
        console.log('A new connection');
        socket.on('data',function(data){
                console.log(data.toString());
        });
        socket.on('end',function(){
                console.log('Closed connection');
        });
});

server.on('error',console.log);

fs.unlink(pipename,function(){
        server.listen(pipename);
})

//Test unix-socket server:
setInterval(function(){
        var stream = net.connect(pipename);
        stream.on('error',console.log);
        stream.write('hello');
        stream.end();
},2000);

错误现象

  1. C程序调用open打开文件时出错:
const char* pipename = "/tmp/pipe1";
int hPipe = open(pipename, O_WRONLY); //Error: No such device or address
  1. 执行echo 'Hello World!' > /tmp/pipe1时报错:
bash: /tmp/pipe1: No such device or address
  1. ls -l /tmp能看到该文件,类型标识为s:
srwxr-xr-x 1 root root    0 Sep 16 03:20 pipe1

原因分析

你混淆了Linux下两种不同的IPC机制:

  • Node.js代码创建的是Unix域套接字,文件类型标识为s,它是基于套接字API的双向通信对象,不能用普通文件的open()/write()操作
  • 你预期的是命名管道(FIFO),文件类型标识为p,这类文件可以用普通文件IO接口操作

解决办法

提供两种针对性方案:

方案1:修改C程序,用Unix套接字API连接Node.js服务

Unix套接字需要用套接字专用API操作,示例C代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

int main() {
    const char* pipename = "/tmp/pipe1";
    int sockfd;
    struct sockaddr_un addr;

    // 创建Unix套接字
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 配置套接字地址
    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, pipename, sizeof(addr.sun_path) - 1);

    // 连接到Node.js服务端
    if (connect(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) == -1) {
        perror("connect");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 发送数据
    const char* msg = "Hello from C program";
    ssize_t bytes_sent = write(sockfd, msg, strlen(msg));
    if (bytes_sent == -1) {
        perror("write");
    } else {
        printf("Sent %zd bytes: %s\n", bytes_sent, msg);
    }

    close(sockfd);
    return 0;
}

方案2:修改Node.js代码,使用命名管道(FIFO)通信

如果要保留C程序的open()/write()逻辑,Node.js需要切换到FIFO模式:

  1. Node.js端代码:
'use strict';
const fs = require('fs');
const pipename = '/tmp/pipe1';
const FIFO_MODE = 0o666;

// 创建命名管道,已存在则跳过
try {
    fs.mkfifoSync(pipename, FIFO_MODE);
} catch (err) {
    if (err.code !== 'EEXIST') throw err;
}

// 监听FIFO的数据读取
fs.createReadStream(pipename)
    .on('data', (data) => {
        console.log('Received:', data.toString());
    })
    .on('error', (err) => {
        console.error('Read error:', err);
    });

// 测试写入FIFO
setInterval(() => {
    fs.writeFile(pipename, 'Hello from Node.js', (err) => {
        if (err) console.error('Write error:', err);
    });
}, 2000);
  1. C程序无需修改核心逻辑,注意FIFO需要两端都打开才不会阻塞。

注意事项

  • Unix套接字性能更高,适合双向、频繁的IPC场景
  • 命名管道实现简单,适合单向或半双向的简单数据传递
  • 确保文件路径权限正确,避免因权限不足导致的访问失败

内容的提问来源于stack exchange,提问作者Mehrdad Nazmdar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:50:27