如何使用 IPCUnix 域套接字在 Node.js首选 Express 模块服务器和 C++ 应用程序之间进行本地通信

如何解决如何使用 IPCUnix 域套接字在 Node.js首选 Express 模块服务器和 C++ 应用程序之间进行本地通信

我有一台机器同时运行一些 C++ 应用程序和一个 Node.js 服务器

用例: 我希望能够触发我的 C++ 应用程序并使其将一些数据(比如一个字符串)传递到套接字文件中。然后我的 Node.js 服务器将从套接字中获取该数据并通过 TCP 端口将其打印在某个网页上(此处/尚未包含代码)。反过来也应该如此。

到目前为止我所做的: 我能够使用以下代码将我的 Node.js 服务器 中的一些字符串写入套接字文件: server.js

var net = require('net');
var fs = require('fs');
var socketPath = '/tmp/sock';

fs.stat(socketPath,function(err) {
    if (!err) fs.unlinkSync(socketPath);
    var unixServer = net.createServer(function(localSerialConnection) {
        localSerialConnection.on('data',function(data) {
            // data is a buffer from the socket
                    console.log('Something happened!');
        });
        // write to socket with localSerialConnection.write()
                localSerialConnection.write('HELLO\n');
                localSerialConnection.write('I\'m\n');
                localSerialConnection.write('DOING something!\n');
                localSerialConnection.write('with the SOCKS\n');
    });
unixServer.listen(socketPath);
});

使用 nc -U /tmp/sock 和以下输出 https://i.stack.imgur.com/ye2Dx.png 读取内容。

当我运行我的 C++ 代码时:

cpp_socket.cpp

#include <boost/asio.hpp>
#include <iostream>

int main() {
    using boost::asio::local::stream_protocol;
    boost::system::error_code ec;

    ::unlink("/tmp/sock"); // Remove previous binding.
    boost::asio::io_service service;
    stream_protocol::endpoint ep("/tmp/sock");
    stream_protocol::socket s(service);

    std::cout << "passed setup section" << std::endl;
    
    s.connect(ep);

    std::cout << "passed connection" << std::endl;

    std::string message = "Hello from C++!";
    
    std::cout << "before sending" << std::endl;
    boost::asio::write(s,boost::asio::buffer(message),boost::asio::transfer_all());
    /* s.write_some(boost::asio::buffer("hello world!"),ec); */
    std::cout << "after sending" << std::endl;

我得到以下输出:

/cpp_socket 
passed setup section
terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>'
  what():  connect: No such file or directory
Aborted (core dumped)

即使 /tmp/sock 文件仍然存在。

当我删除带有注释的 ::unlink("/tmp/sock"); // Remove previous binding. 时,它会运行,但我的 Node.js 服务器停止运行并且 nc -U /tmp/sock 失去连接。 .write() 和 .write_some() 函数似乎都不起作用。

我认为我错过了一些微不足道的东西,或者我没有遵循 Unix 套接字通信的基本概念。

问题:

  1. 是否可以使用一个 Node.js 服务器应用程序同时侦听 TCP 端口和 UNIX 套接字?
  2. 根据我的输入判断,我是否正确理解了 unix socket 通信的概念?
  3. 我如何从 C++ 中读取写入从/到套接字,最好使用 C++ boost/asio 库。但不一定需要:-)
  4. 我问的问题是否正确?

如您所见,我对这些主题不太熟悉。如果我没有相应地解决我的问题并且不够准确,那是因为我缺乏经验。

非常感谢。让我们进行富有成果的讨论。

解决方法

哦,糟糕。错误一目了然:

::unlink("/tmp/sock"); // Remove previous binding.

移除插座。如果您想连接到它,那可不好。

删除该行使其工作:

passed setup section
passed connection: Success
before sending
after sending

在听者方面:

enter image description here

我想这是可以预料的,因为客户端尚未完成。

,

免责声明: 我让它与 TCP 套接字一起工作,但我想看看它如何与 unix 套接字一起使用。再打开一个端口可能会导致潜在的安全威胁(如果我错了,请纠正我)。因此,如果您(sehe)或有人知道如何实现这一点,请随时分享。由于我无法在 Internet 上的搜索中找到此内容,因此它也可能对其他人有所帮助。

我现在做了什么:

  • 创建一个监听两个端口的 NodeJS 服务器。一个用于网络浏览器的端口,一个用于 C++ 应用程序的端口
  • 通过一个端口连接 C++ 应用程序
  • 使用 telnet 发送字符串

server.js

const net = require('net');
const express = require('express');
const app = express();
const c_port = 6666;
const si_port = 8888;

//------------- From here Browser stream is handled -------------//

app.get('/',(req,res)=>{
  res.send('Hello from Node!');
});

app.get('/index.html',res) => {
  res.sendFile(__dirname + "/" + "index.html");
});

app.listen(si_port,res)=>{
  console.log(`Listening on http://localhost:${si_port}`);
});


//------------- From here C++ stream is handled -------------//

var server = net.createServer(function(c) { //'connection' listener
  console.log('client connected');
    c.on('end',function() {
    console.log('client disconnected');
  });
  c.write('hello\r\n');

  c.on('data',function(data){
  var read = data.toString();
  console.log(read);
    // var message = c.read();
    // console.log(message);
  })
  // c.pipe(c);
  c.write('Hello back to C++'); // But only if you shut down the server
});

server.listen(c_port,function() { //'listening' listener
  console.log(`Listening for input from C++ application on port:${c_port}`);
});

client.cpp

#include <iostream>
#include <boost/asio.hpp>

int main(int argc,char* argv[]) 
{

    if(argc != 4){
        std::cout<<"Wrong parameter\n"<<"Example usage ./client 127.0.0.1 1234 hello"<<std::endl;   
        return -1;
    }

    auto const address = boost::asio::ip::make_address(argv[1]);
    auto const port = std::atoi(argv[2]);
    std::string msg = argv[3];
    
    msg = msg + '\n';

    boost::asio::io_service io_service;
    
    //socket creation
    boost::asio::ip::tcp::socket socket(io_service);
    
    //connection
    boost::system::error_code ec;
    socket.connect( boost::asio::ip::tcp::endpoint( address,port ),ec);
    if(ec){std::cout<<ec.message()<<std::endl; return 1;}
    
    // request/message from client
    //const string msg = "Hello from Client!\n";
    boost::system::error_code error;
    boost::asio::write( socket,boost::asio::buffer(msg),error );

    if(error){
        std::cout << "send failed: " << error.message() << std::endl;
    }
    
    // getting response from server
    boost::asio::streambuf receive_buffer;
    boost::asio::read(socket,receive_buffer,boost::asio::transfer_all(),error);
    
    if( error && error != boost::asio::error::eof ){
        std::cout << "receive failed: " << error.message() << std::endl;
    }
    else{
        const char* data = boost::asio::buffer_cast<const char*>(receive_buffer.data());
        std::cout << data << std::endl;
  }
    return 0;
}

使用 telnet localhost 6666 我可以轻松地在该端口上发送随机字符串。 使用附加参数和字符串执行我的二进制文件,我能够从我的 C++ 发送一些数据:./clientcpp 127.0.0.1 6666 "HELLO from C++"。这是输出: enter image description here

再次非常感谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res