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\n");
        }
        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;

posted @ 2015-02-27 12:09  tilly_chang  阅读(646)  评论(0编辑  收藏  举报