当前位置: 首页 > news >正文

关于Unix Domain Socket的使用入门

起因

最近在看ceph的动态参数修改。就观察到了Unix Domain Socket这个技术。
那这个UDS具体是个啥呢?
Unix Domain Socket(UDS) 是一种 在同一台计算机上的不同进程之间进行通信的机制。你可以把它理解为“本地版的网络套接字”,但它不走网络,只在操作系统内部完成数据交换。

一个例子

假定我有个c++程序,里面有个变量,我现在想修改它怎么办?
简单说一个c++每隔几秒钟打印一个字符串,这个字符串就存在进程的内存里,并不是从磁盘里实时读取的。现在想让程序打印另一个字符串怎么办?
来看代码:

服务端代码


// server.cpp
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <signal.h>const char* SOCKET_PATH = "/tmp/uds_example.sock";// 全局变量,被循环输出
std::string message = "Hello from C++ server!";// 清理 socket 文件
void cleanup() {unlink(SOCKET_PATH);std::cout << "\n[Server] Shutdown: socket cleaned up.\n";
}// 信号处理(Ctrl+C)
void sigint_handler(int sig) {cleanup();exit(0);
}int main() {int server_fd, client_fd;struct sockaddr_un addr;socklen_t len;// 注册信号处理signal(SIGINT, sigint_handler);// 创建 UDS socketserver_fd = socket(AF_UNIX, SOCK_STREAM, 0);if (server_fd == -1) {perror("[Server] socket");return 1;}// 绑定地址memset(&addr, 0, sizeof(addr));addr.sun_family = AF_UNIX;strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);// 删除旧 socket(如果存在)unlink(SOCKET_PATH);if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("[Server] bind");close(server_fd);return 1;}if (listen(server_fd, 1) == -1) {perror("[Server] listen");close(server_fd);return 1;}std::cout << "[Server] Listening on " << SOCKET_PATH << std::endl;std::cout << "[Server] Initial message: \"" << message << "\"" << std::endl;std::cout << "[Server] Waiting for client..." << std::endl;// 正确设置非阻塞模式int flags = fcntl(server_fd, F_GETFL, 0);        // 先获取原有标志if (flags == -1) {perror("fcntl getfl");close(server_fd);return 1;}fcntl(server_fd, F_SETFL, flags | O_NONBLOCK);  // 再加上 O_NONBLOCKwhile (true) {// 尝试接受连接(非阻塞)client_fd = accept(server_fd, (struct sockaddr*)&addr, &len);if (client_fd != -1) {char buffer[1024];ssize_t bytes = recv(client_fd, buffer, sizeof(buffer) - 1, 0);if (bytes > 0) {buffer[bytes] = '\0';std::cout << "\n[Server] Received from client: \"" << buffer << "\"" << std::endl;message = buffer;  // 更新全局变量}if (config.message=="shutdown"){std::cout << "[Server] i get shutdown command" << std::endl;break;}close(client_fd);} else if (errno != EAGAIN && errno != EWOULDBLOCK) {// 真正的错误if (errno != EINTR) {usleep(100000); // 短暂休眠避免忙等}}// 持续输出当前消息std::cout << "[Server] Current message: \"" << message << "\"" << std::endl;usleep(500000); // sleep 0.5s}close(server_fd);cleanup();return 0;
}

client端代码

// client.cpp
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>const char* SOCKET_PATH = "/tmp/uds_example.sock";int main(int argc, char* argv[]) {if (argc != 2) {std::cerr << "Usage: " << argv[0] << " <new_message>\n";std::cerr << "Example: " << argv[0] << " \"Hello World!\"\n";return 1;}std::string message = argv[1];int sockfd;struct sockaddr_un addr;// 创建 UDS socketsockfd = socket(AF_UNIX, SOCK_STREAM, 0);if (sockfd == -1) {perror("[Client] socket");return 1;}// 设置地址memset(&addr, 0, sizeof(addr));addr.sun_family = AF_UNIX;strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);// 连接服务端if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("[Client] connect");std::cerr << "[Client] Is the server running?\n";close(sockfd);return 1;}// 发送消息if (send(sockfd, message.c_str(), message.length(), 0) == -1) {perror("[Client] send");close(sockfd);return 1;}std::cout << "[Client] Sent: \"" << message << "\"\n";close(sockfd);return 0;
}

大家试试呗

http://www.dtcms.com/a/409823.html

相关文章:

  • 机器视觉系统中工业相机的常见类型及其特点、应用
  • RTT操作系统(4)
  • 基于卷积神经网络的 CIFAR-10 图像分类实验报告
  • 微服务项目->在线oj系统(Java-Spring)----[前端]
  • 做网站撘框架小米手机如何做游戏视频网站
  • 如何建自己网站做淘宝客黄骅港吧
  • 交叉口内CAV调度:轨迹优化与目标速度规划,助力智能交通无缝运行!
  • Navicat 技术指引 | KingbaseES 专用 AI 助手
  • 如何优化Android app耗电量
  • 面试复习题---Flutter 资深专家
  • 在 C# 中将邮件转换为 PDF | MSG 转 PDF | EML 转 PDF
  • 【LangChain4j+Redis】会话记忆功能实现
  • Android Handler的runWithScissors方法
  • 180课时吃透Go语言游戏后端开发3:Go语言中其他常用的数据类型
  • 在 Android 11 上实现 WiFi 热点并发支持(同时开启 STA + AP 模式)
  • 济南高新区网站建设wordpress举报插件
  • html 占位符
  • GPT-5 Codex正式上线 Azure AI Foundry(国际版)
  • C++设计模式之结构型模式:享元模式(Flyweight)
  • STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
  • 全文 -- Vortex: Extending the RISC-V ISA for GPGPU and 3D-Graphics Research
  • 设计网站推荐理由公司网站备案电话
  • 事件驱动与CDS:基于FHIR R5 Subscriptions与Bulk Data的再考察(下)
  • Tigshop开源商城系统 Java v5.2.2 / PHP v5.1.6版本正式发布(ES搜索上新)
  • 仙游县住房和城乡建设局网站1元涨1000粉丝网站
  • 【Linux】进程概念(六):进程地址空间深度解析:虚拟地址与内存管理的奥秘
  • 网站怎么做微信登录界面wordpress restful
  • Linux下写一个简陋的shell程序
  • OpenSource - 异构数据库数据与结构同步工具dbswitch
  • 首次披露潮玩成长性,量子之歌敲响新财年重估的钟声