Я пытаюсь общаться между программой NodeJS и C, используя именованные каналы в Linux. Моя серверная программа написана в NodeJS:
'use strict';
const net = require('net');
const pipename = '/tmp/pipe1';
const fs = require('fs');
let server = net.createServer(function(socket){
console.info('A new connection');
socket.on('data',function(data){
console.info(data.toString());
});
socket.on('end',function(){
console.info('Closed connection');
});
});
server.on('error',console.info);
fs.unlink(pipename,function(){
server.listen(pipename);
})
//Test unix-socket server:
setInterval(function(){
var stream = net.connect(pipename);
stream.on('error',console.info);
stream.write('hello');
stream.end();
},2000);
Однако, когда я хочу открыть канал внутри C даже после того, как сервер NodeJS уже запущен, я получаю сообщение об ошибке:
const char* pipename = "/tmp/pipe1";
int hPipe = open(pipename, O_WRONLY); //Error: No such device or address
Когда я пытаюсь сделать echo 'Hello World!' > /tmp/pipe1, я получаю bash: /tmp/pipe1: No such device or address. Но ls -l /tmp дает:
srwxr-xr-x 1 root root 0 Sep 16 03:20 pipe1
Как я могу решить эту проблему?





/tmp/pipe1 не является файлом канала. Это файл сокета. Вот что означает ведущий s в srwxr-xr-x.
И перенаправление Bash, такое как >, не поддерживает файлы сокетов. Вам нужно использовать API сокетов, чтобы открыть файл.
С помощью strace(e.g. strace bash -c 'echo > /tmp/sockfile') мы можем увидеть:
...
openat(AT_FDCWD, "/tmp/sockfile", ...) = -1 ENXIO (No such device or address)
...
Таким образом, код ошибки — ENXIO, которому соответствует сообщение об ошибке No such device or address. Bash просто вызывает стандартный C API (например, strerror), чтобы напечатать ошибку.
Пример кода для клиентской стороны:
int
sock_connect(char * sockpath)
{
int sock_fd;
struct sockaddr_un srv_addr = { 0 };
sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sock_fd < 0) {
return -1;
}
srv_addr.sun_family = AF_LOCAL;
snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", sockpath);
if (connect(sock_fd, (struct sockaddr *) & srv_addr, sizeof(srv_addr)) < 0) {
return -1;
}
return sock_fd;
}