格式化抽象本地地址
传统AF_UNIX套接口名字的麻烦之一就在于总是调用文件系统对象。这不是必须的,而且也不方便。如果原始的文件系统对象并没有删除,而在bind调用时使用相同的文件名,名字赋值就会失败。
Linux 2.2内核使得为本地套接口创建一个抽象名了成为可能。他的方法就是使得路径名的第一个字节为一个空字节。在路径名中空字节之后的字节才会成为抽象名字的一部分。下面的这个程序是上一个例子程序的修改版本。这个程序采用了一些不同的方法来创建一个抽象的名字。
/***************************************** 
 * af_unix2.c
 *
 * AF_UNIXSocket Example
 * CreateAbstract Named AF_UNIX/AF_LOCAL
 *******************************************/ 
#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/stat.h>
#include<sys/un.h>

/*
 * Thisfunction reports the error and 
 * exits backto the shell:
 */
static voidbail(const char *on_what)
{
   perror(on_what);
   exit(1);
}

int main(intargc,char **argv,char **envp)
{
   int z;        /* Status return code */
   int sck_unix;    /* Socket */
   struct sockaddr_un adr_unix;    /* AF_UNIX */
   int len_unix;    /* length */
   const char pth_unix[]    /* Abs .Name */
       = "Z*MY-SOCKET*";

/*
    * Create an AF_UNIX (aka AF_UNIX) socket:
    */
   sck_unix = socket(AF_UNIX,SOCK_STREAM,0);
   if(sck_unix == -1)
       bail("socket()");

/* 
    * Form an AF_UNIX Address
    */
   memset(&adr_unix,0,sizeof adr_unix);
   adr_unix.sun_family = AF_UNIX;
   strncpy(adr_unix.sun_path,pth_unix,
           sizeof adr_unix.sun_path-1)
       [sizeof adr_unix.sun_path-1] = 0;
   len_unix = SUN_LEN(&adr_unix);

/*
    * Now make first byte null
    */
   adr_unix.sun_path[0] = 0;
    
   z = bind(sck_unix,(struct sockaddr *)&adr_unix,len_unix);
   if(z == -1)
       bail("bind()");
   /*
    * Display all of our bound sockets:
    */
   system("netstat -pa --unix 2>/dev/null |"
           "sed -n '/^Active UNIX/,/^Proto/P;"
           "/af_unix/P'");
   /*
    * Close and unlink our socket path:
    */
   close(sck_unix);
   return 0;
   /*
    * Now bind the address to the socket:
    */
}
这个程序的运行结果如下:
$ ./af_unix2
Active UNIX domainsockets (servers and established)
Proto RefCntFlags    Type     State I-Node PID/Programname Path
unix0       []      STREAM         1041435186/af_unix2    @*MY- SOCKET*
$
从这个输出结果中我们可以看到,套接口地址是以 @*MYSOCKET*的名字出现的。开头的@标志是为netstat命令用来标识抽象UNIX套接口名字。其余的字符是拷贝到字符数组剩余位置的字符。注意@字符出现在我们的Z字符应出现的地方。
整个程序的步骤与前一个程序的相同。然而,地址的初始化步骤有一些不同。这些步骤描述如下:
1 在第31行和第32行定义了套接口抽象名字的字符串。注意字符串的第一个字符为Z。在这个字符串这个多余的字符只是起到占位的作用,因为实际上他会在第6步被一个空字节代替。
2 在第45行通过调用memset函数将整个结构初始经为0。
3 在第47行将地址族设置为AF_UNIX。
4 在第49行使用strncpy函数将抽象名字拷贝到adr_unix.sun_path中。在这里要注意,为了SUN_LEN()宏的使用在目的字符数组的放置了一个结束的空字节。否则就不需要这个结束的空字节。
5 在第53通过Linux所提供的SUN_LEN() C 宏来计算地址的长度。这个宏会在sun_path[]上调用strlen函数,所以需要提供了一个结束字符。
6 这一步是新的:sun_path[]数组的第一个字节被设置为空字节。如果使用SUN_LEN()宏,必须最后执行这一步。
在这一部分,我们了解了如何来创建AF_LOCAL和AF_UNIX的套接口地址。为了计算套接口地址的长度,我们使用SUN_LEN()宏。然而,当计算抽象套接口名字时,我们要十分注意。

格式化抽象本地地址(实战linux socket编程)的更多相关文章

  1. Linux socket 编程中存在的五个隐患

    前言:         Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是   开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它 ...

  2. Linux Socket 编程简介

    在 TCP/IP 协议中,"IP地址 + TCP或UDP端口号" 可以唯一标识网络通讯中的一个进程,"IP地址+端口号" 就称为 socket.本文以一个简单的 ...

  3. Linux Socket编程

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  4. Linux Socket编程(不限Linux)【转】

    转自:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几 ...

  5. Linux Socket编程(不限Linux)

    "一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...

  6. Socket详解-Linux Socket编程(不限Linux)

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  7. Windows Socket和Linux Socket编程的区别 ZZ

    socket相关程序从Windows移植到Linux下需要注意的: 1)头文件 Windows下winsock.h/winsock2.h Linux下sys/socket.h 错误处理:errno.h ...

  8. Linux socket编程示例(最简单的TCP和UDP两个例子)

    一.socket编程 网络功能是Uinux/Linux的一个重要特点,有着悠久的历史,因此有一个非常固定的编程套路. 基于TCP的网络编程: 基于连接, 在交互过程中, 服务器和客户端要保持连接, 不 ...

  9. Linux Socket编程-(转自吴秦(Tyler))

    "一切皆Socket!" 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信 ...

随机推荐

  1. pytest-调整测试用例的执行顺序

    场景:未考虑按自然顺序执行时,或想变更执行顺序,比如增加 数据的用例要先执行,再执行删除的用例.测试用例默认是按名 称顺序执行的. • 解决: • 安装:pip install pytest-orde ...

  2. mysql8的坑

    plugin caching_sha2_password could not be loaded 我在mac上用Sequel Pro连数据库的时候,会报出以上错误,这是应为8.0.11把身份认证插件改 ...

  3. mysql数据库用户权限设置

    设置用户权限:格式:grant 权限列表 on 数据库名.表名 to '用户名'@'来源地址' identified by '密码'; * 权限列表:用于列出授权的各种数据库操作,通过逗号进行分割,如 ...

  4. Spring集成RMI实现远程调用

    前提: 1.开发工具: jdk tomcat ecplise,开发工具的使用本篇不做介绍. 2.需具备以下知识:javase servelt web rmi spring maven 一.关于RMI ...

  5. Android各种蓝牙设备的UUID(转)

    转自:http://www.14blog.com/archives/481 UUID是“Universally Unique Identifier”的简称,通用唯一识别码的意思.对于蓝牙设备,每个服务 ...

  6. Schema约束与DTD约束

    现将Schema约束与DTD约束实现的一个实例截图出来: 1.DTD 1.1 DTD文件 1.2 DTD实现 2.Schema 2.1 Schema约束 2.2 Schema实现

  7. icomoon字体图标引用代码

    1.第一步在样式里声明字体:告诉别人我们自己定义的字体. @font-face{ /*声明字体 引用字体*/ font-family:'icomoon'; src:url('fonts/icomoon ...

  8. Manacher模板(O(n)内求最长回文串长度)

    转自:https://segmentfault.com/a/1190000008484167 /* 由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以 ...

  9. SQL复制数据表及表结构

    select * into 目标表名 from 源表名 insert into 目标表名(fld1, fld2) select fld1, 5 from 源表名 以上两句都是将'源表'的数据插入到'目 ...

  10. Array排序和List排序

    public class SortTest { public static void main(String[] args) { int arr[]={12,4,45,23,5,7,9,33}; Sy ...