首页 > 其他 > 详细

UNIX网络编程读书笔记:UNIX域协议

时间:2014-03-12 16:27:06      阅读:441      评论:0      收藏:0      [点我收藏+]

bubuko.com,布布扣概述

UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同。UNIX域协议可视为进程间通信(IPC)方法之一。

UNIX域提供两类套接口:字节流套接口(类似TCP)和数据报套接口(类似UDP)。

使用UNIX域套接口的理由有3个:

bubuko.com,布布扣在源自Berkeley的实现中,UNIX域套接口往往比通信两端位于同一主机的TCP套接口快出一倍。

bubuko.com,布布扣UNIX域套接口可用于在同一个主机上的不同进程间传递描述字。

bubuko.com,布布扣UNIX域套接口较新的实现把客户的凭证(用户ID和组ID)提供给服务器,从而能够提供额外的安全检查措施。

UNIX域中用于标识客户和服务器的协议地址是普通文件系统中的路径名。这些路径名不是普通的UNIX文件:除非把它们和UNIX域套接口关联起来,否则无法读写这些文件。

bubuko.com,布布扣UNIX域套接口地址结构

在头文件<sys/un.h>中定义了UNIX域套接口地址结构:

struct sockaddr_un {
    sa_family_t    sun_family;       /* AF_LOCAL */
    char           sun_path[104];    /* null-terminated pathname */
};

存放在sun_path数组中的路径名必须以空格字符结尾。

实现提供的SUN_LEN宏以一个指向sockaddr_un结构的指针为参数并返回该结构的长度,其中包括路径名中非空字节数。

未指定地址(通配地址),通过以空字符串作为路径名指示,也就是一个sun_path[0]值为0的地址结构。这是UNIX域中与IPv4的INADDR_ANY常值以及IPv6的IN6ADDR_ANY_INIT常值等价的一个地址。

POSIX把UNIX域协议重新命名为“本地IPC”,以消除它对于UNIX操作系统的依赖。历史性的AF_UNIX常值变为AF_LOCAL。尽管POSIX努力使它独立于操作系统,它的套接口地址结构仍然保留_un后缀。

bubuko.com,布布扣实例:UNIX域套接口的bind调用

创建一个UNIX域套接口,往其上bind一个路径名,再调用getsockname输出这个绑定的路径名。

bubuko.com,布布扣
#include <sys/un.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int
main(int argc, char **argv)
{
    int                   sockfd;
    socklen_t             len;
    struct sockaddr_un    addr1, addr2;

    if(argc != 2)
    {
        printf("usage: unixbind <pathname> ");
        exit(0);
    }
    sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
    unlink(argv[1]);    /* 如果文件系统中已存在该路径名,bind将会失败。为此我们先调用unlink删除这个路径名,以防止它已经存在。 */
    bzero(&addr1, sizeof(addr1));
    addr1.sun_family = AF_LOCAL;
    strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path) - 1);
    bind(sockfd, (struct sockaddr *)&addr1, SUN_LEN(&addr1));

    len = sizeof(addr2);
    getsockname(sockfd, (struct sockaddr *)&addr2, &len);
    printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);
    
    exit(0);
}
bubuko.com,布布扣

运行结果如下:

bubuko.com,布布扣

bubuko.com,布布扣socketpair函数

socketpair函数创建两个随后连接起来的套接口。本函数仅适用于UNIX域套接口。

#include <sys/socket.h>
int socketpair(int family, int type, int protocol, int sockfd[2]);
返回:0——成功,-1——出错

family参数必须为AF_LOCAL;

protocol参数必须为0;

type参数可以是SOCK_STREAM,也可以是SOCK_DGRAM。

新创建的两个套接口描述字作为sockfd[0]和sockfd[1]返回。

本函数类似于UNIX的pipe函数:返回两个彼此连接的描述字。事实上,源自berkeley的实现通过执行与socketpair一样的内部操作给出pipe接口。

这样创建的两个套接口不曾命名;也就是说其中没有涉及隐式的bind调用。它与调用pipe创建的普通UNIX管道类似,差别在于流管道是全双工的,即两个描述字都是既可读又可写。

POSIX不要求全双工管道。

bubuko.com,布布扣套接口函数

当用于UNIX域套接口时,套接口函数中存在一些差异和限制:

bubuko.com,布布扣由bind创建的路径名缺省访问权限应为0777(属主用户、组用户和其他用户都可读、可写并可执行),并按照当前umask值进行修正。

bubuko.com,布布扣与UNIX域套接口关联的路径名应该是一个绝对路径名,而不是一个相对路径名。

bubuko.com,布布扣在connect调用中指定的路径名必须是一个当前捆绑在某个打开的UNIX域套接口上的路径名,而且它们的套接口类型(字节流或数据报)也必须一致。

bubuko.com,布布扣调用connect连接一个UNIX域套接口涉及的权限测试等同于调用open以只读方式访问相应的路径名。

bubuko.com,布布扣UNIX域字节流套接口类似于TCP套接口:它们都为进程提供一个无记录边界的字节流接口。

bubuko.com,布布扣如果对于某个UNIX域字节流套接口的connect调用发现这个监听套接口的队列已满,调用就立即返回一个ECONNREFUSED错误。这一点不同于TCP:如果TCP监听套接口的队列已满,TCP监听端就忽略新到达的SYN,而TCP连接发起端将数次发送SYN进行重试。

bubuko.com,布布扣UNIX域数据报套接口类似UDP套接口:它们都提供一个保留记录边界的不可靠的数据报服务。

bubuko.com,布布扣在一个未绑定的UNID域套接口上发送数据报不会自动给这个套接口捆绑一个路径名,这一点不同于UDP套接口:在一个未绑定的UDP套接口上发送UDP数据报导致给这个套接口捆绑一个临时端口。这一点意味着除非数据报发送端已经捆绑一个路径名到它的套接口,否则数据报接收端无法发回应答数据报。类似地,对于某个UNIX域数据报套接口的connect调用不会给本套接口绑定一个路径名,这一点不同于TCP和UDP。

未完待续。。。

UNIX网络编程读书笔记:UNIX域协议,布布扣,bubuko.com

UNIX网络编程读书笔记:UNIX域协议

原文:http://www.cnblogs.com/nufangrensheng/p/3595610.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!