格式化抽象本地地址
传统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. 纯Delphi 原生写的 上传到七牛的功能

    上传文件到七牛, 支持分片分段上传, 适用于Delphi XE, 10等新版本 分两个函数: uploadToQiniu 和 directUploadToQiniu uploadToQiniu 这个函 ...

  2. TypeScript和JavaScript的区别

    JavaScript和TypeScript的对比 注:参考https://juejin.im/entry/5a52ed336fb9a01cbd586f9f做的笔记 概要介绍 JavaScript Ja ...

  3. IDEA Caused by: java.lang.OutOfMemoryError: PermGen space

    错误:OutOfMemoryError: PermGen space 非堆溢出(永久保存区域溢出) 解决方法: 在Run/Debug configuration 的你要运行行的tomcat里面的 vm ...

  4. linux学习总结--linux100day(day1)

    写在前面:我是一名在学习linux的小学生,最近在学习python时,我的老师推荐了github上的一本教材“python100day”,100day里面的内容由浅入深,且都具备详细的例子,对于我这个 ...

  5. tomcat的首次登录配置

    登录tomcat时需要输入账号密码,而账号密码需要在配置文件中配置好才能使用. 此处我们先点击取消,tomcat会弹出一个提示界面: 这个界面的大致意思是: 401未经授权 您无权查看此页面. 如果您 ...

  6. Linux 100个常用指令

    1.ls 列出目录内容. 文件属性: -:普通文件 d:目录文件 b:块设备 c:字符设备文件 l:符号连接文件 p:命令管道 s:套接字文件 文件权限: 9位数字,每3位一组 文件硬链接次数 文件所 ...

  7. Codeforces 251C Number Transformation DP, 记忆化搜索,LCM,广搜

    题意及思路:https://blog.csdn.net/bossup/article/details/37076965 代码: #include <bits/stdc++.h> #defi ...

  8. bcpow — 任意精度数字的乘方

    bcpow — 任意精度数字的乘方 说明 string bcpow ( string $left_operand , string $right_operand [, int $scale ] ) 左 ...

  9. java 获取String出现最多次数的字段

    package hello; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator ...

  10. 遍历实例化swiper

    var list = $('.p04-s2 li'); list.each(function (index) { new Swiper ($(this).find('.swiper-container ...