PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

环境说明

  无

前言


  在《记一次有趣的hwclock写RTC的PermissionDenied错误》(https://www.cnblogs.com/Iflyinsky/p/17841708.html 或者 https://https/flyinskyin2013.github.io/2023/11/19/blog_idx_125/)中,我们提到了关于高通板卡,我们无法通过hwclock来写入rtc时钟。但是我们通过相关调查、测试、分析后发现,高通自己搞了一套新的方式来写入rtc时钟,这种特殊方法用的技术就是abstract socket。这也是我在工作中第一次遇到abstract socket,这里做一个简要的记录。

Abstract sockets


  

说明

  我们先不看代码,我们先看看abstract sockets具体是什么样子的。我们都知道,我们可以通过netstat查看unix socket相关的连接信息。我们来看看ubuntu 18.04里面用netstat查看unix socket信息如下:

  注意图中我们看到的path那一列,除了普通的路径外,我们会看到一些奇怪的名字,每个名字前面都有一个@符号。这种特殊的名字,就是abstract sockets。

简介

  首先,根据文档,对于传统的uds来说,其支持两种类型,它们分别是:有名字的、未命名的。对于linux来说,这里还支持一种独立于文件系统的,且是一种不可移植的扩展,这就是我们要介绍的就是抽象的这种类型。

  对于抽象的uds来说,socket权限对其来说是没有意义的,例如umask、fchown、fchmod等不会影响其访问权限。

  对于抽象的uds来说,抽象的uds将会自动被销毁,当所有的引用打开的socket关闭的时候。

  对于抽象的uds来说,和有名字的uds最大的区别在于sockaddr_un.sun_path[0]是0x00,如果大家对c风格的字符串有印象,这是一个字符串的终止符。abstract uds的名字由sockaddr_un.sun_path的其余字节给出(这个时候的0x00是没有特殊意义的),其长度是addrlen - sizeof(sa_family_t)来定义的。

使用小例子

server

#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h> int main(int argc, char * argv[])
{
int uds = socket(AF_UNIX, SOCK_STREAM, 0);
if (uds < 0) perror("socket:"); struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
memset(addr.sun_path, 0x0, 108);
const char * addr_path = "abstract_test";
memcpy(addr.sun_path + 1, addr_path, strlen(addr_path)); int ret = bind(uds, &addr, strlen(addr_path) + sizeof(sa_family_t) + 1);
if (ret < 0) perror("bind:"); ret = listen(uds, 2);
if (ret < 0) perror("listen:"); struct sockaddr_un r_addr;
socklen_t r_addr_len;
int _new = accept(uds, &r_addr, &r_addr_len);
if (_new < 0) perror("accept:");
char r_msg[256];
memset(r_msg, 0x0, 256);
ret = read(_new, r_msg, 256);
if (ret < 0) perror("read:");
printf("client msg = %s\n", r_msg);
write(_new, "hello client", sizeof("hello client")); sleep(5); close(uds);
return 0;
}

client.c

#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h> int main(int argc, char * argv[])
{
int uds = socket(AF_UNIX, SOCK_STREAM, 0);
if (uds < 0) perror("socket:"); struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
memset(addr.sun_path, 0x0, 108);
const char* addr_path = "abstract_test";
memcpy(addr.sun_path + 1, addr_path, strlen(addr_path)); int ret = connect(uds, &addr, strlen(addr_path) + sizeof(sa_family_t) + 1);
if (ret < 0) perror("connect:"); write(uds, "hello server", sizeof("hello server")); char r_msg[256];
memset(r_msg, 0x0, 256);
read(uds, r_msg, 256);
printf("server msg %s\n", r_msg); sleep(5);
close(uds);
return 0;
}

  首先我们撸了两个例子,一个是服务端,一个是客户端。

  首先我们运行客户端。然后通过netstat查看我们的socket。如下图:

  当我们运行服务端后,再次运行客户端,就会看到我们传输的消息,如下图:

后记


  通过我们如上的实验,可以看到其和普通的uds用法差不多,唯一的区别就是其不需要和文件系统绑定了。

  其实,这种不和文件系统绑定的特性,可以给我们带来更多有趣的用法(例如:不受文件系统权限影响进行通信),后续有缘分享。

参考文献


打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)

PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。

初识uds之abstract socket的更多相关文章

  1. Envoy 基础教程:使用 Unix Domain Socket(UDS) 与上游集群通信

    Envoy Proxy 在大多数情况下都是作为 Sidecar 与应用部署在同一网络环境中,每个应用只需要与 Envoy(localhost)交互,不需要知道其他服务的地址.然而这并不是 Envoy ...

  2. Java Socket:Java-NIO-ServerSocketChannel

    ServerSocketChannel 让我们从最简单的ServerSocketChannel来开始对socket通道类的讨论 ServerSocketChannel是一个基于通道的socket监听器 ...

  3. Unix domain socket IPC

    UNIX Domain socket 虽然网络socket也可用于同一台主机的进程间通讯(通过lo地址127.0.0.1),但是unix domain socket用于IPC更有效率:不需要经过网络协 ...

  4. socket编程相关阐述

    一.socket初识 ①服务端 import socket server = socket.socket() server.bind(('127.0.0.1', 8080)) server.liste ...

  5. PYTHON学习之路_PYTHON基础(8)

    学习内容: Python模块介绍 1.经典类 or 新式类 2.抽象接口 3.静态方法.类方法.属性方法 4.反射 5.异常处理 6.socket编程初识 7.用socket实现get.put文件等功 ...

  6. 分布式计算框架Gearman原理详解

    什么是Gearman? Gearman提供了一个通用的应用程序框架,用于将工作转移到更适合于工作的其他机器或流程.它允许你并行工作,负载平衡处理,并在语言间调用函数.它可用于从高可用性网站到传输数据库 ...

  7. gearman(异步计算)学习

    Gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调 用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/C++版本.目前大部分源码都是(Gearmand服务 ...

  8. Linux configure关于交叉编译的参数设置【转】

    转自:http://blog.csdn.net/darennet/article/details/9003005 configure的参数众多,一般包括如下 --srcdir=DIR 这个选项对安装没 ...

  9. gearman参数说明

    -b, –backlog=BACKLOG 连接请求队列的最大值 -d, –daemon Daemon 守护进程化 -f, –file-descriptors=FDS 可打开的文件描述符数量 -h, – ...

  10. gearman知识文章

    一篇文章: Gearman介绍.调研.测试与原理分析 gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/ ...

随机推荐

  1. P2572 [SCOI2010] 序列操作 题解

    题解:序列操作 比较综合的 ds 题,综合了线段树常见的几种操作:维护最大子段和.区间翻转.区间求和.区间覆盖 . 维护子段和常见的我们维护三类东西: 前缀最长连续段.后缀最长连续段.当前区间上的最大 ...

  2. 主机--Host

    概念:主机是用于构建应用程序和服务.封装应用资源的对象,负责程序的启动和生命周期的管理,简单来说主机即应用程序. 主机运行:当主机运行的时候,他会将托管在服务容器集合里面注册的IHostService ...

  3. Linux 在线安装MySQL8.0

    1.更新Linux yum yum update 2.安装wget工具(如果已经安装wget,可以跳过该步骤) yum install wget 3.使用wget下载MySQL Yum Reposit ...

  4. 从零开始学正则(七:终章),详解常用正则API与你可能不知道的正则坑

     壹 ❀ 引 花了差不多半个月的晚上时间,正则入门学习也步入尾声了,当然正则的学习还将继续.不得不说学习成效非常明显,已能看懂大部分正则以及写出不太复杂的正则,比如帮组长写正则验证文件路径正确性,再如 ...

  5. Laravel入坑指南(11)——列队

    很高兴,我们来到了Laravel入坑指南的第11篇.这一系列的文章已经接近尾声了,在这一节里面,我们一起讨论列队的用法. 列队,顾名思义,将需要处理的任务一个一个排好队,等待处理程序来处理.这机的列队 ...

  6. java常用包下载地址(非maven)

    httpclient与httpcore: http://hc.apache.org/downloads.cgi jdbc: https://dev.mysql.com/downloads/connec ...

  7. 微信小程序引入iconfont实现添加自定义颜色图标

    说明 最近搞微信小程序,需要添加一些图标,发现引入iconfont还是有几个步骤,就记录下来分享以下. 以下配置方法支持自定义颜色的. 操作步骤 1. 在iconfont网站挑选自己需要的图标,添加到 ...

  8. MYSQL服务无法启动:InnoDB: .\ibdata1 can't be opened in read-write mode

    今天在那做实验倒腾mysql数据库,后来发现服务无法启动,查看日志报错如下: 2015-01-07 17:48:54 9136 [ERROR] InnoDB: .\ibdata1 can't be o ...

  9. win10下开启IIS部署网站

    今天测试一个有关IIS的安全漏洞用了下win10下的IIS,记录一下,供网友参考. 1.启用IIS 依次点开: 控制面板-----程序----启用或关闭Windows功能 以下图片中打钩的地方全勾上. ...

  10. 使用SYS_CONTEXT

    使用SYS_CONTEXT 1.什么是SYS_CONTEXT? SYS_CONTEXT 函数是Oracle提供的一个获取环境上下文信息的预定义函数. 该函数用来返回一个指定namespace下的par ...