格式化抽象本地地址
传统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. win10 虚拟机VMware 14中CentOS7文件共享

    一,环境 主机:win10 家庭版 软件:VMware 14 系统:CentOS 7 二,设置共享文件 右键虚拟机->选择设置 如图:创建共享文件 三,安装VMware Tools 然后进入ce ...

  2. mac 完全卸载vscode

    原文分隔线====================== while writing go this morning, I found that the wrong code are not under ...

  3. servlet的ServletConfig接口

    ServletConfig接口 A servlet configuration object used by a servlet container to pass information to a ...

  4. ubuntu 设置root密码

  5. 【mysql升级步骤】windows mysql版本升级 ,mysql 5.6 升级到5.7.27

    最近博主由于工作原因需要把之前安装好的的mysql 5.6.44版本卸载,然后安装mysql 5.7.*版本. 前提:为什么要升级到5.7版本? 因为博主在5.6版本上执行脚本时候报出异常:to yo ...

  6. 存储过程分页查询和在ado.net中的使用,返回查询总数

    1.创建查询分页的存储过程 CREATE PROCEDURE PageQuery @tableName VARCHAR(),-- 表名 @strWhere VARCHAR(),-- 查询条件 @col ...

  7. spring framework三个版本的下载包区别

    docs:该文件夹下包含Spring的相关文档.开发指南及API参考文档:dist:该文件夹下包含Spring jar包.文档.项目等内容:schema:里面包含了Spring4所用到的xsd文件:

  8. python 爬取拉勾网

    import requestsimport randomimport timeimport osimport csvimport pandas as pdreq_url = 'https://www. ...

  9. go函数声明

    go函数声明 这是一个很好的机会去介绍函数支持多值返回.查看下面3个函数:一个没有返回值,一个返回一个值,一个返回2个值. func log(message string) { } func add( ...

  10. 【Redis】分布式锁RedLock

    普通实现 说道Redis分布式锁大部分人都会想到: 1.setnx+lua, 2.setkey value px milliseconds nx. - 获取锁(unique_value可以是UUID等 ...