文档章节

网络编程学习——Unix域协议

thanatos_y
 thanatos_y
发布于 2016/04/20 16:27
字数 1903
阅读 39
收藏 0
点赞 1
评论 0

1 概述

  Unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方式,所用API就是在不同主机上执行客户/服务器通信所用的API(套接字API)。

  Unix域提供两类套接字:字节流套接字(类似于TCP)和数据报套接字(类似UDP)尽管也提供原始套接字,不过它的语义不曾见于任何文档,作者们也未见过任何使用它的程序,POSIX也没有它的定义。

  使用Unix域套接字有以下3个理由。

  1. 在BSD的实现中,Unix域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍。X Window System发挥了Unix域套接字的这个优势。当一个X11客户启动并打开到X11服务器的连接时,该客户检查DISPLAY环境变量的值,其中指定服务器的主机名、窗口和屏幕。如果服务器与客户出于同一主机,客户就打开一个到服务器的Unix域字节流连接,否则打开一个到服务器的TCP连接。

  2. Unix域套接字可用于在同一个主机上的不同进程之间传递描述符。

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

  Unix域中用于标识客户和服务器的协议地址是普通文件系统中的路径名。这些路径名不是普通的Unix文件:除非把它们和Unix域套接字关联起来, 否则无法读写这些文件。

2 Unix域套接字地址结构

  Unix域套接字地址结构如下。

#include <sys/un.h>
/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
struct sockaddr_un
  {
    __SOCKADDR_COMMON (sun_);
    char sun_path[108];        /* Path name.  */
  };

  存放在sun_path数组中的路径名必须以空字符结尾。

例子:Unix域套接字的bind调用

  下面程序创建一个Unix域套接字,往其上bind一个路径名,再调用getsockname输出这个绑定的路径名。

3 socketpair函数

  socketpair函数创建两个随后连接起来的套接字。不函数仅适用于Unix域套接字。

#include <sys/socket.h>
/* Create two new sockets, of type TYPE in domain DOMAIN and using
   protocol PROTOCOL, which are connected to each other, and put file
   descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
   one will be chosen automatically.  Returns 0 on success, -1 for errors.  */
extern int socketpair (int __domain, int __type, int __protocol,
               int __fds[2]) __THROW;

  __domain参数必须为AF_LOACL,__protocol参数必须为0。__type参数既可以是SOCK_STREAM,也可以是SOCK_DGRAM。新建的两个套接字描述符作为__fds[0]和__fds[1]返回。

  这样创建两个套接字不曾命名,也就是说其中没有涉及隐式的bind调用。指定type参数为SOCK_STREAM调用socketpair得到的结果称为流管道(pipe)。它与调用pipe创建的普通Unix管道类似,差别在于流管道是全双工的,即两个描述符都是既可读又可写的。

4 套接字函数

  1. 由bind创建的路径名默认访问权限应为0777,并按照当前umask值进行修正。

  2. 与Unix域套接字关联的路径名应该是一个绝对路径名,而不是一个相对路径名。

  3. 在connect调用中指定路径名必须是一个当前绑定在某个打开的Unix域套接字上的路径名,而且它们的套接字类型(字节流或数据报)也必须一致。

  4. 调用connect连接一个Unix域套接字涉及的权限设置测试等同于调用open以只写方式访问相应的路径名。

  5. Unix域字节流套接字类似TCP套接字:它们都为进程提供一个无记录边界的字节流接口。

  6. 如果对于某个Unix域字节流套接字的connect调用发现这个监听套接字的队列已满,调用就立即返回一个ECONNREFSUED错误。

  7. Unix域数据报套接字类似于UDP套接字:它们都提供一个保留记录边界的不可靠的数据报服务。

  8. 在一个未绑定的Unix域套接字上发送数据报不会自动给这个套接字捆绑一个路径名,这一点不同于UDP套接字:在一个未绑定的UDP套接字上发送UDP数据报导致给这个套接字捆绑一个临时端口。

5 描述符传递

  当考虑从一个进程到另一个进程传递打开的描述符时,我们通常会想到:

  • fork调用返回之后,子进程共享父进程的所有打开的描述符;

  • exec调用执行之后,所有描述符通常保持打开状态不变。

  当前的Unix系统提供了用于从一个进程向任一其他进程传递一打开的描述符的方法。也就是说,这两个进程之间无需存在亲缘关系,譬如父子进程关系。这种技术要求首先在这两个进程之间创建一个Unix域套接字,然后使用sendmsg跨这个套接字发送一个特殊消息。这个消息由内核来专门处理,会把打开的描述符从发送进程传递到接收进程。

  在两个进程之间传递描述符涉及的步骤如下。

  1. 创建一个字节流的或数据报的Unix域套接字。

  2. 发送进程通过调用返回描述符的任一Unix函数打开一个描述符,这些函数的例子有open、pipe、mkfifo、socket和accpet。

  3. 发送进程创建一个msghdr结构,其中含有待传递的描述符。

  4. 接收进程调用recvmsg在来自步骤1的Unix域套接字上接收这个描述符。

 

描述符传递的例子

  图1-1展示了上述步骤(1):通过调用socketpair创建一个流管道后的mycat进程。我们以后以[0]和[1]标示socketpair返回的两个描述符。

图1-1 使用socketpair创建流管道后的mycat进程

  mycat进程接着调用fork,进程再调用exec执行openfile程序。父进程关闭[1]描述符,子进程关闭[0]描述符。图1-2展示如此处理后的结果。

图1-2 启动执行openfile程序后的mycat进程

  父进程必须给openfile传递三条信息:(1)待打开文件的路径名,(2)打开方式(只读、读写或只写),(3)流管道本进程端。

  下面是mycat程序,把一个文件复制到标准输出。

  如果把my_open调用换成open调用,这个简单的程序就只是把一个文件复制到标准输出。

  read_fd函数接收数据和一个描述符。

  下面是openfile程序。它取得三个必须传入的命令行参数,并调用通常的open函数。

  最后一个函数是write_fd函数。

 

6 接收发送者的凭证

  通过Unix域套接字作为辅助数据传递的另一种数据是用户凭证(user credential)。

#include <bits/socket.h>
/* User visible structure for SCM_CREDENTIALS message */
struct ucred
{
  pid_t pid;            /* PID of sending process.  */
  uid_t uid;            /* UID of sending process.  */
  gid_t gid;            /* GID of sending process.  */
};

例子

  该函数由子进程在父进程接受了一个新的客户连接并调用fork之后调用。

 

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
thanatos_y
粉丝 7
博文 90
码字总数 315059
作品 0
成都
程序员
0-Linux 网络编程学习笔记导航

学习交流群: Linux 学习交流群 610441700 说明:本系列文章并不能取代 《UNP》这本旷世之作,文章中难免有错误与不足之处,希望读者们遇到有疑问的地方可以加群互相交流,共同进步。写这一系...

q1007729991 ⋅ 2017/04/04 ⋅ 0

所看书籍记录

《程序员教程(第三版)》 《深入理解计算机系统》 《程序员的自我修养--链接、装载与库》(两遍) 《编译原理(龙书)》 《现代操作系统(第三版)》 《图解网络硬件》 《图解TCP/IP》 《数据...

thanatos_y ⋅ 2016/03/14 ⋅ 0

Linux网络编程必看书籍推荐

首先要说讲述TCP/IP的书很多,其中有3泰书很全。 分别是《TCP/IP详解》三卷本,《用TCP/IP进行网际互连》三卷本,《TCP/IP指南》+《IPv6》四卷本 其中TCP/IP详解的作者还写了另外2本经典著作...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

Linux网络编程必看书籍推荐

首先要说讲述TCP/IP的书很多,其中有3泰书很全。 分别是《TCP/IP详解》三卷本,《用TCP/IP进行网际互连》三卷本,《TCP/IP指南》+《IPv6》四卷本 其中TCP/IP详解的作者还写了另外2本经典著作...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

我的网络开发之旅——socket编程

上一篇文章《TCP/IP协议分析》讲述了自己是如何和网络领域的开发扯上关系的。正如从招聘网站上抽出的几个关键词“TCP/IP, Socket, 多线程”可见,协议分析并不是网络开发的主流,通常我们所说...

yaocoder ⋅ 2014/09/21 ⋅ 0

如何学好C语言?为什么会有学的既不深,也不扎实,半吊子的感觉

如何学好C语言?为什么会有学的既不深,也不扎实,半吊子的感觉 C/C++学习,解答,技术内容更多尽在:C/C++学习群:99816772 我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编...

这个人很懒什么都没留下 ⋅ 2017/12/20 ⋅ 0

我的网络开发之旅——TCP/IP协议分析

之前在当地的一期技术沙龙做了一个《网络开发那些事》的技术分享,讲述了自己职业生涯从事的与网络相关的开发工作。在接触这类开发之前一直在从事业务系统或者单机系统的开发,说真的那时感觉...

yaocoder ⋅ 2014/09/16 ⋅ 0

十一年C/C++编程老手给小白学习C语言的句句肺腑之言,令人深思

我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编到一定的时候,发现能力到了瓶颈,既不深,也不扎实,半吊子。比如:你长期地使用Java和.NET ,这些有虚拟机的语言对于开发便...

小辰GG ⋅ 2017/12/04 ⋅ 0

Linux网络编程书籍

计算机网络知识 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的《计算机网络》第五版,这本书难易适中。 目前已经是第五版,本书作者80年代就开发出MINIX,是一个用于操作系统教学的类U...

krircc ⋅ 2015/04/01 ⋅ 0

如何学好C语言

我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编到一定的时候,发现能力到了瓶颈,既不深,也不扎实,半吊子。比如:你长期地使用Java和.NET ,这些有虚拟机的语言对于开发便...

邪恶的小Y ⋅ 2011/08/16 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

C++内存映射文件居然是这样?!

内存映射文件大家都时不时听过,但它到底是个什么?赶紧来看看吧 内存映射文件到底是干嘛的呢?让我们先来思考下面几个问题: 如果您想读的内容大于系统分配的内存块怎么办?如果您想搜索的字...

柳猫 ⋅ 29分钟前 ⋅ 0

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 今天 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部