Linux下的socket编程实践(六)Unix域协议和socketpair传递文件描述符

UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所使用的API相同。UNIX域协议可以视为IPC方法之一,Unix域协议主要用在同一台机子(仅能用于本地进程间的通信)的不同进程之间传递套接字。为什么不用TCP或者UDP套接字呢?

1)在同一台主机上, UNIX域套接字更有效率, 几乎是TCP的两倍(由于UNIX域套接字不需要经过网络协议栈,不需要打包/拆包,计算校验和,维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程, 而且UNIX域协议机制本质上就是可靠的通讯, 而网络协议是为不可靠的通讯设计的)。

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

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

注意:UNIX域套接字也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX套接字也是可靠的,消息既不会丢失也不会顺序错乱。Unix域协议表示协议地址的是路径名,而不是Internet域的IP地址和端口号。

UNIX域套接字地址结构:

#define UNIX_PATH_MAX    108  
struct sockaddr_un  
{  
    sa_family_t sun_family;               /* AF_UNIX */  
    char        sun_path[UNIX_PATH_MAX];  /* pathname */  
};
至于通信程序的话,和使用TCP的通信并没有很大的区别,下面给出基于UNIX域套接字的server/client程序源码

/**Server端**/  

int main()  
{   
    int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);  //使用AF_UNIX 或者AF_LOCAL 
    if (listenfd == -1)  
        err_exit("socket error");  
  
    char pathname[] = "/tmp/test_for_unix";  
    unlink(pathname);//如果文件系统中已存在该路径名,bind将会失败。为此我们先调用unlink删除这个路径名,以防止它已经存在 
    struct sockaddr_un servAddr;  
    servAddr.sun_family = AF_UNIX;  
    strcpy(servAddr.sun_path, pathname);  
    if (bind(listenfd, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1)  
        err_exit("bind error");  
    if (listen(listenfd, SOMAXCONN) == -1)  
        err_exit("listen error");  
  
    while (1)  
    {  
        int connfd = accept(listenfd, NULL, NULL);  
        if (connfd == -1)  
        {
       	    if(connfd==EINTR)
       	    continue;
       	    err_exit("accept");
        }
    } 
	return 0; 
} 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值