IPC 之 命名unix域套接字

来源:互联网 发布:windows 10 mobile壁纸 编辑:程序博客网 时间:2024/05/16 14:12

简介

        unix域套接字用于在同一台机器上运行的进程之间的通信。虽然因特网域套接字可用于同一目的,但是unix域套接字效率更高。unix域套接字仅仅复制数据;它们并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不要产生顺序号,无需发送确认报文。

        unix域套接字的地址由sockaddr_un结构表示。sockaddr_un结构按下列形式定义在头文件<sys/un.h>中

        structsockaddr_un{

               sa_family_t sun_family;    /*AF_UNIX */

               char       sun_path[108];   /* pathname */

        };

但是在FreeBSD等其他操作系统中,sockaddr_un结构定义如下:

        structsockaddr_un{

               unsignedchar sun_len;     /* length including null */

               sa_family_t   sun_family; /*AF_UNIX */

               char          sun_path[104];   /* pathname */

        };

        sockaddr_un结构的sun_path成员包含一路径名。当我们将一个地址绑定至unix域套接字时,系统用该路径名创建一类型为S_IFSOCK的文件。该文件仅用于向客户进程告知套接字名字。该文件不能打开,也不能由应用程序用于通信。

        如果当我们试图绑定地址时,该文件已存在,那么bind请求会失败。关闭套接字时,并不自动删除该文件,所以必须确保在应用程序终止前,对该文件执行解除链接操作。

示例程序


服务端

#include<stdio.h>#include<stdlib.h>#include<stddef.h>#include<unistd.h>#include<errno.h>#include<sys/socket.h>#include<sys/un.h> #definePATH "/tmp/ipc_sock"#defineQUEUE_LEN 10 intmain(int argc, char *argv[]){    int                serfd, clifd, len, ret;    char               rcv_buf[1024];    pid_t               pid;    struct sockaddr_un server_addr, client_addr;     if((serfd = socket(AF_UNIX,SOCK_STREAM, 0)) < 0){        perror("Createserver socket error");        exit(EXIT_FAILURE);    }     memset(&server_addr, 0, sizeof(server_addr));    server_addr.sun_family= AF_UNIX;    strncpy(server_addr.sun_path, PATH, sizeof(PATH));    len =offsetof(struct sockaddr_un, sun_path) + strlen(PATH);     unlink(server_addr.sun_path);     if(bind(serfd, (structsockaddr *)&server_addr, len) < 0){        perror("Bindserver socker error");        close(serfd);        unlink(PATH);        exit(EXIT_FAILURE);    }if(listen(serfd,QUEUE_LEN) < 0){        perror("Listenserver socker error");        close(serfd);        unlink(PATH);        exit(EXIT_FAILURE);    }     len = sizeof(client_addr);     for(;;){        if((clifd = accept(serfd,(structsockaddr *)&client_addr, &len)) < 0){            perror("Cannot accept client connect request");            continue;        }         pid = fork();         if(pid < 0){            perror("forkerror!");        }else if(pid == 0){            ret = read(clifd, rcv_buf, sizeof(rcv_buf));            if(ret <= 0){                perror("readerror");            }else{                printf("receivedata : %s\n", rcv_buf);            }        }else{        }    }     close(serfd);close(clifd);unlink(PATH);     return(0);}

客户端

#include<stdio.h>#include<stdlib.h>#include<stddef.h>#include<unistd.h>#include<sys/socket.h>#include<sys/un.h> #definePATH "/tmp/ipc_sock" intmain(int argc, char **argv){    int     fd, ret, len;    char    *send_buf= "hello,world!";    struct sockaddr_un addr;     if((fd = socket(PF_UNIX,SOCK_STREAM, 0)) < 0){        perror("Createsocket error");        exit(EXIT_FAILURE);    }     memset(&addr, 0, sizeof(addr));    addr.sun_family= AF_UNIX;    strncpy(addr.sun_path, PATH, strlen(PATH));    len =offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);     if((ret = connect(fd, (structsockaddr *)&addr, len)) < 0){        perror("Cannot connect server");        close(fd);        exit(EXIT_FAILURE);    }     ret = write(fd,send_buf, strlen(send_buf));    if(ret < 0){        printf("writeerror!");    }     close(fd);     return(0);}


0 0
原创粉丝点击