一、UNIX Domain Socket
概念:
UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC)

特点:
1. 它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等
2. 只是将应用层数据从一个进程拷贝到另一个进程。

工作模式:
SOCK_DGRAM     类似于UDP
SOCK_STREAM    类似于TCP

用途:
UNIX Domain Socket可用于两个没有亲缘关系的进程,是全双工的,是目前使用最广泛的IPC机制
比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的


二、工作流程
与网络socket的不同点:
    1.  address family为AF_UNIX
    2.  unix domain socket不需要IP和端口,取而代之的是文件路径来表示“网络地址”
            原理:            
            UNIXDomain socket用结构体sockaddr_un表示,是一个socket类型的文件在文件系统中的路径
            这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回
            
            UNIX Domain Socket客户端一般要显式调用bind函数,而不象网络socket一样依赖系统自动分配的地址。
            客户端bind的socket文件名可以包含客户端的pid,这样服务器就可以区分不同的客户端

工作流程:
服务器端:创建socket—绑定文件(端口)—监听—接受客户端连接—接收/发送数据—…—关闭
客户端:   创建socket—绑定文件(端口)—连接—发送/接收数据—…—关闭


三、阻塞和非阻塞(SOCK_STREAM方式)
读写操作有两种操作方式:阻塞和非阻塞
1.阻塞模式下
阻塞模式下,发送数据方和接收数据方的表现情况如同命名管道

2.非阻塞模式
在send或recv函数的标志参数中设置MSG_DONTWAIT,则发送和接收都会返回。如果没有成功,则返回值为-1,errno为EAGAIN 或 EWOULDBLOCK

四.实例
服务端代码:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#define UNIX_DOMAIN "/data/local/tmp/ndk_cmd"
int main(void) {
    int listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (listen_fd < 0) {
        perror("cannot create communication socket\n");
        return 1;
    }
    //set server addr_param
    struct sockaddr_un srv_addr;
    srv_addr.sun_family = AF_UNIX;
    strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1);
    unlink (UNIX_DOMAIN);
    //bind sockfd & addr
    int ret = bind(listen_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
    if (ret == -1) {
        perror("cannot bind server socket");
        close(listen_fd);
        unlink(UNIX_DOMAIN);
        return 1;
    }
    //listen sockfd
    ret = listen(listen_fd, 1);
    if (ret == -1) {
        perror("cannot listen the client connect request");
        close(listen_fd);
        unlink(UNIX_DOMAIN);
        return 1;
    }
    //have connect request use accept
    struct sockaddr_un clt_addr;
    int len = sizeof(clt_addr);
    int com_fd = accept(listen_fd, (struct sockaddr*) &clt_addr, &len);
    if (com_fd < 0) {
        perror("cannot accept client connect request");
        close(listen_fd);
        unlink(UNIX_DOMAIN);
        return 1;
    }
    //read and printf sent client info
    printf("/n=====info=====/n");
    static char recv_buf[1024];
    for (int i = 0; i < 4; i++) {
        memset(recv_buf, 0, 1024);
        int num = read(com_fd, recv_buf, sizeof(recv_buf));
        printf("Message from client (%d)) :%s\n", num, recv_buf);
    }
    close(com_fd);
    close(listen_fd);
    unlink(UNIX_DOMAIN);
    return 0;
}

客户端代码:
#include <stdio.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
int main(void) {
    //creat unix socket
    int connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
    if (connect_fd < 0) {
        perror("cannot create communication socket");
        return 1;
    }
    static struct sockaddr_un srv_addr;
    srv_addr.sun_family = AF_UNIX;
    strcpy(srv_addr.sun_path, "/data/local/tmp/ndk_cmd");
    //connect server
    int ret = connect(connect_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));
    if (ret == -1) {
        perror("cannot connect to the server");
        close(connect_fd);
        return 1;
    }
    char snd_buf[1024];
    memset(snd_buf, 0, 1024);
    strcpy(snd_buf, "message from client");
    //send info server
    for (int i = 0; i < 4; i++)
        write(connect_fd, snd_buf, sizeof(snd_buf));
    close(connect_fd);
    return 0;
}

运行结果:





ndk学习16: unix domain socket的更多相关文章

  1. monitor a local unix domain socket like tcpdump

    Can I monitor a local unix domain socket like tcpdump? - Super User https://superuser.com/questions/ ...

  2. 由一个简单需求到Linux环境下的syslog、unix domain socket

    本文记录了因为一个简单的日志需求,继而对linux环境下syslog.rsyslog.unix domain socket的学习.本文关注使用层面,并不涉及rsyslog的实现原理,感兴趣的读者可以参 ...

  3. UNIX DOMAIN SOCKET效率

    关于UNIX DOMAIN SOCKET和普通udp socket的对比 在TX1(4核A57 1.7GHz)的板卡上进行测试,每个包大小设置为1024,全速收发,UDS的速度在90Mbps左右,UD ...

  4. nginx、php-fpm默认配置与性能–TCP socket还是unix domain socket【转】

    原文地址:https://www.cnxct.com/default-configuration-and-performance-of-nginx-phpfpm-and-tcp-socket-or-u ...

  5. (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误

    一个困扰我两天的问题, Google和Baidu没有找到解决方法! 此文为记录这个问题,并给出原因和解决方法. 1.Unix domain socket简介 unix域协议并不是一个实际的协议族,而是 ...

  6. 问题解决:psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

    错误提示: psql: could not connect to server: No such file or directory Is the server running locally and ...

  7. Unix Domain Socket 域套接字实现

    主要注意流程: STREAM SOCKET: Server :  socket() --->  bind() ---> listen()  ---> accept() Client: ...

  8. libpqxx接口的在linux下的使用,解决psql:connections on Unix domain socket "/tmp/.s.PGSQL.5432"错误

    在项目中使用postgresql数据库时要求在windows和linux双平台兼容.于是在windows下使用的接口在linux下爆出异常: psql:connections on Unix doma ...

  9. [dev][socket] unix domain socket删除socket文件

    问题 在使用unix domain socket的时候,bind之后,会在本地路径里 产生一个与path对应的socket文件. 如何正确的在用完socket之后,对其销毁呢? 方案 使用 unlin ...

随机推荐

  1. Red Black Tree in C

    http://web.mit.edu/~emin/www.old/source_code/red_black_tree/index.html

  2. js搜索输入关键词

    function getInput(val,a){ var id = 'ser-key'; if(a=='focus'){ document.getElementById(id).value=''; ...

  3. php引用计数的基本知识

    每个php变量存在一个叫"zval"的变量容器中.一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息.第一个是"is_ref",是个bool ...

  4. Python之迭代器和生成器

    Python 迭代器和生成器 迭代器 Python中的迭代器为类序列对象(sequence-like objects)提供了一个类序列的接口,迭代器不仅可以对序列对象(string.list.tupl ...

  5. isArray polyfill

    Array.isArray在ie9+浏览器上已经支持,可以放心使用.在垃圾浏览器上,可以说使用如下polyfill(出自MDN) if(!Array.isArray){ Array.isArray = ...

  6. python 默认全局变量

    python 内置默认全局变量print (vars()) __doc__ #py文件头部的注释 '''我是一个注释例子''' print (vars()) __file__ #当前文件路劲__pac ...

  7. iwebshop二次开发

    1.iwebshop中写hello world ① 动作action方式 controllers目录下,然后创建text.php. <?php class Test extends IContr ...

  8. Struts2源码浅析-ConfigurationProvider

    ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...

  9. 【转】【整理】将Linux脚本中的正常输出,警告,错误等信息输出到文件中

     本文来自:http://blog.csdn.net/woshinia/article/details/18040063   很早以前  编译的时候 就在用 2>&1,但是一直没有生成一 ...

  10. 开机自动连接/断开VPN 批处理

    或许大家在工作或生活中有接触到VPN,如果使用Windows自带的VPN来连接,每次开机要像宽带拨号那样,右击该VPN连接图标,然后选择“连接”(如果未记住密码甚至还要输入密码),然后点击确定,有点麻 ...