UNIX Domain SOCKET 是在Socket架构上发展起来的用于同一台主机的进程间通讯(IPC)。它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等。只是将应用层数据从一个进程拷贝到另一个进程。UNIX Domain SOCKET有SOKCET_DGRAM和SOCKET_STREAM两种模式,类似于UDP和TCP,但是面向消息的UNIX socket也是可靠的,消息既不会丢失也不会顺序错乱。

UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。

使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。

UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

服务端: socket -> bind -> listen -> accept -> recv/send -> close 
客户端: socket -> connect -> recv/send -> close

  • 开始创建socket

  1. int socket(int domain, int type, int protocol)
  2. domain(域) : AF_UNIX
  3. type : SOCK_STREAM/ SOCK_DGRAM :
  4. protocol : 0

SOCK_STREAM(流) : 提供有序,可靠的双向连接字节流。 可以支持带外数据传输机制, 
无论多大的数据都不会截断 
SOCK_DGRAM(数据报):支持数据报(固定最大长度的无连接,不可靠的消息),数据报超过最大长度,会被截断.

获取到socket文件描述符之后,还要将其绑定一个文件上
 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : 传入sock的文件描述符
addr : 用sockaddr_un表示
addrlen : 结构体长度

struct sockaddr_un {
    sa_family_t sun_family; /* AF_UNIX */
    char sun_path[UNIX_PATH_MAX];   /* pathname */
};

监听客户端的连接
int listen(int sockfd, int backlog);
sockfd : 文件描述符
backlog : 连接队列的长度

接受客户端的连接
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
Unux domain socket不存在客户端地址的问题,因此这里的addr和addrlen参数可以设置为NULL

server 端程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<errno.h>
#include<stddef.h>
#include<unistd.h>

#define MAX_CONNECT_NUM 2
#define BUFFER_SIZE 1024
const char *filename="uds-tmp";

int main()
{
    int fd,new_fd,len,i;
    struct sockaddr_un un;
    fd = socket(AF_UNIX,SOCK_STREAM,0);
    if(fd < 0){
        printf("Request socket failed!\n");
        return -1;
    }
    un.sun_family = AF_UNIX;
    unlink(filename);
    strcpy(un.sun_path,filename);
    if(bind(fd,(struct sockaddr *)&un,sizeof(un)) <0 ){
        printf("bind failed!\n");
        return -1;
    }
    if(listen(fd,MAX_CONNECT_NUM) < 0){
        printf("listen failed!\n");
        return -1;
    }
    while(1){
        struct sockaddr_un client_addr;
        char buffer[BUFFER_SIZE];
        bzero(buffer,BUFFER_SIZE);
        len = sizeof(client_addr);
        //new_fd = accept(fd,(struct sockaddr *)&client_addr,&len);
        new_fd = accept(fd,NULL,NULL);
        if(new_fd < 0){
            printf("accept failed\n");
            return -1;
        }
        int ret = recv(new_fd,buffer,BUFFER_SIZE,0);
        if(ret < 0){
            printf("recv failed\n");
        }
        for(i=0; i<10; i++){
            printf(" %d",buffer[i]);
        }
        close(new_fd);
        break;
    }
    close(fd);
}

client 端程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<errno.h>
#include<stddef.h>
#include<unistd.h>
#define BUFFER_SIZE 1024
const char *filename="uds-tmp";

int main()
{
    struct sockaddr_un un;
    int sock_fd;
    char buffer[BUFFER_SIZE] = {1,2,3};
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path,filename);
    sock_fd = socket(AF_UNIX,SOCK_STREAM,0);
    if(sock_fd < 0){
        printf("Request socket failed\n");
        return -1;
    }
    if(connect(sock_fd,(struct sockaddr *)&un,sizeof(un)) < 0){
        printf("connect socket failed\n");
        return -1;
    }
    send(sock_fd,buffer,BUFFER_SIZE,0);

close(sock_fd);
    return 0;
}

[转帖]UNIX SOCKET简介的更多相关文章

  1. UNIX SOCKET编程简介

    1  .  Layered Model of Networking Socket  编程的层次模型如下图所示,   最上面是应用层,应用层下面的是  SOCKET API  层,再下面是传输层和网络层 ...

  2. 网络编程(socket简介)

    socket简介 Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中 ...

  3. Another MySQL daemon already running with the same unix socket的解决

    问题出现: 每周一需要备份一次数据库,即从服务器MySQL导出sql文件,再导入到我机器上虚拟机的MySQL里.但是今天早上连不上,我进入控制台用#service mysqld start强行启动,报 ...

  4. Nginx 中 fastcgi_pass 监听端口 unix socket和tcp socket差

    Nginx 中 fastcgi_pass 监听端口 unix socket和tcp socket差别   Nginx连接fastcgi的方式有2种:unix domain socket和TCP,Uni ...

  5. Unable to start MySQL service. Another MySQL daemon is already running with the same UNIX socket

    Unable to start MySQL service. Another MySQL daemon is already running with the same UNIX socket 特征 ...

  6. 启动Mysql报错:Another MySQL daemon already running with the same unix socket.

    启动Mysql报错: Another MySQL daemon already running with the same unix socket. 删除如下文件即可解决 /var/lib/mysql ...

  7. Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  8. MySQL“Another MySQL daemon already running with the same unix socket” 报错信息处理

    Mysql "Another Mysql daemon already running with the same unix socket" 解决办法:rm var/lib/mys ...

  9. unicorn与nginx通讯--[ruby unix socket]

    [龍昌博客] http://www.xefan.com/archives/84146.html unicorn是如何与nginx通讯的——介绍ruby中的unix socket Ruby 应用服务典型 ...

  10. [daily][netcat] 在UNIX socket上使用netcat

    概述 默认情况下,系统里边带的netcat,也就是nc.支持tcp,udp,ipv4,ipv6但是不支持unix socket. 而且,telnet也不支持. 除非自己写一个,不然很不方便. 另一个n ...

随机推荐

  1. 轻量化动态编译库 Natasha v8.0 正式发布!

    .NET8.0 与 动态编译 Hello 各位小伙伴,我于 2024年1月10日 发布了 Natasha 一个全新的里程碑版本 v8.0,对于老用户而言,此次发布版本号跨度较大,是因为我决定使用新的版 ...

  2. 微信小程序本地测试报错 IllegalArgumentException

    在微信小程序本地测试时出现 IllegalArgumentException 错误,解决方法将https换成http Note: further occurrences of HTTP request ...

  3. 扎根CNCF社区贡献五年是怎样的体验?听听华为云原生开源团队的负责人怎么说

    摘要:本月我们要重点介绍王泽锋(Kevin Wang),他是 CNCF 社区的长期贡献者,华为云原生开源团队的负责人,KubeEdge 和 Volcano 项目的联合创始人.Kevin 回答了几个关于 ...

  4. Flutter加固原理及加密处理

    ​ 引言 为了保护Flutter应用免受潜在的漏洞和攻击威胁,加固是必不可少的措施之一.Flutter加固原理主要包括代码混淆.数据加密.安全存储.反调试与反分析.动态加载和安全通信等多个方面.通过综 ...

  5. Asp.net MVC 跨域设置

    .Net Core 跨域 <system.webServer> <httpProtocol> <customHeaders> <add name=" ...

  6. Kubernetes(K8S) 集群安全机制

    概述 访问K8S集群,需要经过三个步骤完成具体操作 认证 鉴权(授权) 准入控制 进行访问时,过程中需要经过 ApiServer,做统一协调,比如门卫,访问过程中需要证书.token.或者用户名+密码 ...

  7. 【PS算法理论探讨三】 Photoshop中图层样式之 颜色叠加/渐变叠加/图案叠加 算法原理初探讨。

    这三个表面上看上去很简单,我们就先描述简单的部分. 颜色叠加:这个和编辑菜单下的填充 颜色 基本是一个意思,相当于在原有的图层上部添加了一个纯实色的虚拟图层,选项里的不透明度和混合模式和普通的概念是一 ...

  8. EasyUI DataGrid 没有数据

    //判断后台返回数据是否没数据,没数据DataGrid添加一行 $(this).datagrid('appendRow', { itemid: '<div style="text-al ...

  9. SD 信用模拟检查增强

    一.业务流程中需要进行信用模拟检查,但逻辑梳理较为复杂,因此借用交货单创建时信用检查逻辑.但是当交货单信用检查通过时,不创建交货单,因此需要对BAPI:BAPI_OUTB_DELIVERY_CREAT ...

  10. C# golang 开10000个无限循环的性能

    知乎上有人提了个问题,可惜作者已把账号注销了. 复制一下他的问题,仅讨论技术用,侵删. 问题 作者:知乎用户fLP2gX 链接:https://www.zhihu.com/question/63484 ...