UNIX域套接字用于在同一台机器上运行的进程之间的通信。
UNIX域套接字提供流和数据报两种接口。
说明:UNIX域套接字比因特网套接字效率更高。它仅赋值数据;不进行协议处理,如添加或删除网络报头、计算校验和、产生顺序号、发送确认报文等等。 
 
创建一对非命名的、相互连接的UNIX域套接字。
socketpair
 
1.命名UNIX域套接字
1)套接字地址格式,在linux下如下所示
struct sockaddr_un {
 sa_family_t sun_family;
 char sun_path[108];
}
绑定该地址:
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/socket.h>
  4. #include <stdio.h>
  5. #include <sys/un.h>
  6. #include <errno.h>
  7. int main(void)
  8. {
  9. int fd,size;
  10. struct sockaddr_un un;
  11. un.sun_family = AF_UNIX; //unix域
  12. strcpy(un.sun_path, "foo.socket");
  13. if ((fd=socket(AF_UNIX, SOCK_STREAM, ))<) {
  14. printf("socket failed\n");
  15. exit(-);
  16. }
  17. size = sizeof(struct sockaddr_un);
  18. if (bind(fd, (struct sockaddr *)&un, size) < ) {
  19. printf("bind failed:[%s]\n",strerror(errno));
  20. exit(-);
  21. }
  22. printf("UNIX domain socket bound\n");
  23. exit();
  24. }

# ls -l

srwxr-xr-x   1 dev_old_run swdev     0 Sep  7 13:49 foo.socket
第一位代表文件类型,它是一个socket文件
2.唯一连接
1)serv_listen函数
使用bind、listen和accept
2)serv_accept函数
accept
验证客户进程的身份是该套接字的所有者:验证路径名为一个套接字、权限仅允许用户-读、用户-写以及用户-执行、与套接字相关联的3个时间不比当前时间早30秒。
验证身份这块,我这里理解的是服务器对该路径的判断,只要判断出权限,基本上就可以确定客户端的身份了。

  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <sys/stat.h>
  7. #include <time.h>
  8. #include <stddef.h>
  9.  
  10. #define QLEN 10
  11. #define STALE 30
  12.  
  13. int main(void)
  14. {
  15. }
  16.  
  17. //创建服务端,成功返回fd,错误返回值<0
  18. int serv_listen(const char *name)
  19. {
  20. int fd,err,rval, len;
  21. struct sockaddr_un un;
  22.  
  23. if ((fd = socket(AF_UNIX, SOCK_STREAM, )) < )
  24. return -;
  25. unlink(name); //存在文件,先解除连接
  26.  
  27. //填充socket地址结构
  28. memset(&un, , sizeof(un));
  29. un.sun_family = AF_UNIX;
  30. strcpy(un.sun_path, name);
  31.  
  32. //绑定地址到描述符
  33. if (bind(fd, (struct sockaddr *)&un, len) < ) {
  34. rval = -;
  35. goto errout;
  36. }
  37.  
  38. if(listen(fd, QLEN) < ) {
  39. rval = -;
  40. goto errout;
  41. }
  42. return(fd);
  43.  
  44. errout:
  45. err = errno;
  46. close(fd);
  47. errno = err;
  48. return(rval);
  49. }
  50.  
  51. //等待客户连接,并接受它
  52. //同时验证客户的身份
  53. int serv_accept(int listenfd, uid_t *uidptr)
  54. {
  55. int clifd, rval, err;
  56. socklen_t len;
  57. struct sockaddr_un un;
  58. struct stat statbuf;
  59. time_t staletime;
  60.  
  61. len = sizeof(un);
  62. if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < )
  63. return -;
  64.  
  65. //确定客户进程的身份是该套接字的所有者
  66. len -= offsetof(struct sockaddr_un, sun_path); //路径长
  67. un.sun_path[len]=; //增加\0结束符
  68.  
  69. if (stat(un.sun_path, &statbuf) < ) {
  70. rval = -;
  71. goto errout;
  72. }
  73.  
  74. // 文件类型检查
  75. if (S_ISSOCK(statbuf.st_mode)==) {
  76. rval = -;
  77. goto errout;
  78. }
  79.  
  80. // 文件权限检查
  81. if((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||
  82. statbuf.st_mode & S_IRWXU != S_IRWXU) {
  83. rval = -;
  84. goto errout;
  85. }
  86.  
  87. staletime = time(NULL) - STALE;
  88. if (statbuf.st_atime < staletime ||
  89. statbuf.st_ctime < staletime ||
  90. statbuf.st_mtime < staletime) {
  91. rval = -;
  92. goto errout;
  93. }
  94.  
  95. if (uidptr != NULL)
  96. *uidptr = statbuf.st_uid; //返回uid
  97. unlink(un.sun_path);
  98. return(clifd);
  99.  
  100. errout:
  101. err = errno;
  102. close(clifd);
  103. errno = err;
  104. return rval;
  105. }
3)cli_conn函数
客户端会绑定一个路径名,设置其权限。这样在serv_accept中,服务器可以检验这些权限等来验证客户进程的身份。
接着填充服务器的sockaddr_un结构,调用connect连接到服务器。
  1. #include <stdlib.h>
  2. #include <sys/socket.h>
  3. #include <sys/un.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/stat.h>
  7. #include <string.h>
  8. #include <sys/un.h>
  9. #include <stddef.h>
  10.  
  11. #define CLI_PATH "/var/tmp/"
  12. #define CLI_PERM S_IRWXU
  13.  
  14. int main(void)
  15. {
  16. exit();
  17. }
  18.  
  19. int cli_conn(const char *name)
  20. {
  21. int fd, len, err, rval;
  22. struct sockaddr_un un;
  23.  
  24. if ((fd = socket(AF_UNIX, SOCK_STREAM, )) < )
  25. return -;
  26.  
  27. //填充客户端地址
  28. memset(&un, , sizeof(un));
  29. un.sun_family = AF_UNIX;
  30. sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
  31. len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
  32. unlink(un.sun_path);
  33. //绑定到套接字
  34. if (bind(fd, (struct sockaddr *)&un, len) < ) {
  35. rval = -;
  36. goto errout;
  37. }
  38.  
  39. if (chmod(un.sun_path, CLI_PERM) < ) {
  40. rval = -;
  41. goto errout;
  42. }
  43.  
  44. //填充服务端地址
  45. memset(&un, , sizeof(un));
  46. un.sun_family = AF_UNIX;
  47. strcpy(un.sun_path, name);
  48. len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
  49. if (connect(fd, (struct sockaddr *)&un, len) < ) {
  50. rval = -;
  51. goto errout;
  52. }
  53. return(fd);
  54.  
  55. errout:
  56. err = errno;
  57. close(fd);
  58. errno = err;
  59. return(rval);
  60. }

UNIX域套接字(unix domain)的更多相关文章

  1. UNIX 域套接字——UNIX domain socket

    /*********************程序相关信息********************* * 程序编号:015 * 程序编写起始日期:2013.11.30 * 程序编写完成日期:2013.1 ...

  2. UNIX域套接字——UNIX domain socket(DGRAM)

    #define UNIX_PATH_MAX 108 #include <sys/types.h> #include <sys/socket.h> #include <sy ...

  3. Unix域套接字(Unix Domain Socket)介绍【转】

    本文转载自:http://blog.csdn.net/roland_sun/article/details/50266565 版权声明:本文为博主原创文章,未经博主允许不得转载. 在Linux系统中, ...

  4. 高级进程间通信之UNIX域套接字

    UNIX域套接字用于在同一台机器上运行的进程之间的通信.虽然因特网域套接字可用于同一目的,但UNIX域套接字的效率更高.UNIX域套接字仅仅复制数据:它们并不执行协议处理,不需要添加或删除网络报头,无 ...

  5. 《网络编程》Unix 域套接字

    概述 Unix 域套接字是一种client和server在单主机上的 IPC 方法.Unix 域套接字不运行协议处理,不须要加入或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套 ...

  6. UNIX网络编程——UNIX域套接字编程和socketpair 函数

    一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...

  7. UNIX域套接字编程和socketpair 函数

    一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...

  8. Unix域套接字简介

    在Linux系统中,有很多进程间通信方式,套接字(Socket)就是其中的一种.但传统的套接字的用法都是基于TCP/IP协议栈的,需要指定IP地址.如果不同主机上的两个进程进行通信,当然这样做没什么问 ...

  9. unix进程间通信方式(下)-unix域套接字(转)

    在之前的博客中已经总结了其它7种进程间的通信方式.unix域套接字用于在同一台计算机上的进程间通信,虽然因特网域套接字可用于同一目的,但是unix域套接字的效率更高.unix域套接字并不进行协议处理, ...

随机推荐

  1. ios7 ios8 cell中下划线偏移(separator Insets)处理方法

    在ios7中,UITableViewCell左侧会有默认15像素的空白.这时候,设置setSeparatorInset:UIEdgeInsetsZero 能将空白去掉. 但是在ios8中,设置setS ...

  2. 黄聪:路由器WIFI连接无法正常访问个别网站及发送图片

    打开路由,路由默认MTU是1500,改成1472 就解决了

  3. SpringToolSuite/Eclipse中集成的Tomcat无法add Project时的解决版本

  4. eclipse插件

    #eclipse market http://www.eclipse.org/mpc/archive.php http://download.eclipse.org/mpc/mars/ #文件路径 p ...

  5. mir [20161220]

    最近玩backmir,查询了一些资料,突然领悟到原来各个地方的boss攻击和防御都有一定的上限,而相对应的,玩家也有攻击和防御,只要玩家的攻防能对付boss的攻防,就可以无伤打boss. 小时候玩热血 ...

  6. 【转】easyui $.message.alert 点击右上角的关闭按钮时,不执行定义的回调函数

    今天發現這個問題 easyui  $.message.alert  点击右上角的关闭按钮时,不执行定义的回调函数

  7. No Architectures to Compile for (ONLY_ACTIVE_ARCH=

    No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7, VA 运行报错 出现的原因:armv7s是应用在iP ...

  8. lighttpd配置

    1.lighttpd.conf server.modules = ( "mod_access", "mod_alias", "mod_compress ...

  9. ASPNET_MVC学习中的疑问

    1.在mvc..net4.5.Entity Framewor都提供了多种验证规则.  请问,其中不需要提交到服务器验证的验证,是否是在客户端就完成的,还是说像之前的aspnet一样,都得提交到服务器验 ...

  10. ajaxpro返回值类型总结-DataTable(转)

    ajaxpro使用总结系列其他内容 ajaxpro ajaxmethod 重载调用问题 ajaxpro方法ajaxmethod调用示例 ajaxpro返回值类型总结-string,int ajaxpr ...