zoukankan      html  css  js  c++  java
  • LINUX学习:UNIX域协议

    前言介绍:

    1。UNIX域套接字与TCP套接字相比较,在同一台主机的传输四度前者是后者的两倍

    2.UNIX域套接字可以在同一台主机上各进程间传递描述符

    3.UNIX域套接字与传统套接字的区别是用路径名来表示协议族的描述。

    UNIX域地址结构

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

    下面 我们写一个简单的回射服务器来练习一下

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/un.h>
    #define ERR_EXIT(m) 
        do { 
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)
    
    void echo_srv(int conn)
    {
        char recvbuf[1024];
        int ret;
        while(1)
        {
            memset(recvbuf, 0, sizeof(recvbuf));
            ret = read(conn, recvbuf, 1024);
            if(ret ==-1)
            {
                if(errno == EINTR)
                    continue;
                ERR_EXIT("read");
            }else if(ret == 0)
            {
                close(conn);
                printf("client close
    ");
            }
            fputs(recvbuf, stdout);
            write(conn, recvbuf, ret);
        }
    
    
    int main(int argc, const char *argv[])
    {
        //使用UNIX域套接字,在申请套接字时就与TCP不同
        // 需要使用一个PF_UNIX的宏,而不是pf_inet
        int listenfd = socket(PF_UNIX, SOCK_STREAM, 0);
        if(listenfd < 0)
            ERR_EXIT("SoCKET");
    
        struct sockaddr_un servaddr;
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sun_family = AF_UNIX;
        strcpy(servaddr.sun_path, "test_socket");
    
        if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
            ERR_EXIT("bind");
        if(listen(listenfd, SOMAXCONN) < 0)
            ERR_EXIT("listen");
    
        int conn;
        pid_t pid;
        while(1)
        {
            conn = accpet(listenfd, NULL, NULl);
            if(conn == -1)
            {
                if(errno == EINTR)
                    continue;
                ERR_EXIT("accept");
            }
    
            pid = fork();
            if(pid == -1)
                ERR_EXIT("fork");
            if(pid == 0)
            {
                close(listenfd);    
                echo_srv(conn);
                exit(EXIT_SUCCESS);
            }else if(pid > 0)
            {
                close(conn);
    
            }
    
        }
        return 0
    }

    注意:

    1.bind成功将会创建一个文件, 权限为0777, & umask = 755

    2.sun_path最好用一个绝对路径

    3.UNIX域协议支持流式套接字与报式套接口

    4.UNIX与流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED, 这和TCP不同

    如果监听队列满, 会忽略到来的SYN, 这导致对方重传SYN;

  • 相关阅读:
    [LeetCode] 286. Walls and Gates 墙和门
    [LeetCode] Sparse Matrix Multiplication 稀疏矩阵相乘
    [LeetCode] 314. Binary Tree Vertical Order Traversal 二叉树的竖直遍历
    [LeetCode] 337. House Robber III 打家劫舍之三
    [LeetCode] Palindrome Pairs 回文对
    [LeetCode] 302. Smallest Rectangle Enclosing Black Pixels 包含黑像素的最小矩阵
    Nginx安装及配置详解
    Spring Boot项目属性配置
    maven仓库阿里云镜像配置
    maven仓库阿里云镜像配置
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4303018.html
Copyright © 2011-2022 走看看