zoukankan      html  css  js  c++  java
  • ndk学习16: unix domain socket


    一、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_UNIXSOCK_STREAM0);
        if (listen_fd < 0) {
            perror("cannot create communication socket ");
            return 1;
        }
        //set server addr_param
        struct sockaddr_un srv_addr;
        srv_addr.sun_family = AF_UNIX;
        strncpy(srv_addr.sun_pathUNIX_DOMAINsizeof(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, 01024);
            int num = read(com_fd, recv_buf, sizeof(recv_buf));
            printf("Message from client (%d)) :%s ", 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_UNIXSOCK_STREAM0);
        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, 01024);
        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;
    }

    运行结果:









  • 相关阅读:
    MFC 解析xml文件
    数字图像处理-----主成成分分析PCA
    C++设计模式——建造者模式
    总结的文章--未读
    八大排序算法
    C++读取、旋转和保存bmp图像文件编程实现
    数字图像处理-----直方图均衡化
    数字图像处理------中值滤波
    matlab图像基础知识
    MFC最大化显示任务栏
  • 原文地址:https://www.cnblogs.com/bingghost/p/5754684.html
Copyright © 2011-2022 走看看