套接字是通信端点的抽象。与应用程序要使用文件描述符访问文件一样,访问套接字也需要套接字描述符。套接字描述符在UNIX系统是用文件描述符实现的。事实上,许多处理文件描述符的函数(如read和write)都可以处理套接字描述符。

要创建一个套接字,可以调用socket函数。

#include <sys/socket.h>
int socket(int domain, int type, int protocol);
返回值:若成功则返回文件(套接字)描述符,若出错则返回-1

参数domain(域)确定通信的特性,包括地址格式。表16-1总结了由POSIX.1指定的各个域。各个域有自己的格式表示地址,而表示各个域的常数都以AF_开头,意指地址族(address family)。

                                   表16-1 套接字通信域

多数系统还会定义AF_LOCAL域,这是AF_UNIX的别名。AF_UNSPEC域可以代表任何域。历史上,有些平台支持其他网络协议(如AF_IPX为NetWare协议族),但这些协议的域常数没有在POSIX.1标准中定义。

参数type确定套接字的类型,进一步确定通信特征。表16-2总结了由POSIX.1定义的套接字类型,但在实现中可以自由增加对其他类型的支持。

                                                         表16-2 套接字类型

参数protocol通常是0,表示按给定的域和套接字类型选择默认协议。当对同一域和套接字类型支持多个协议时,可以使用protocol参数选择一个特定协议。在AF_INET通信域中套接字类型SOCK_STREAM的默认协议是TCP(传输控制协议)。在AF_INET通信域中套接字类型SOCK_DGRAM的默认协议是UDP(用户数据报协议)。下表(摘自apue第3版)列出了为因特网域套接字定义的协议:

对于数据报(SOCK_DGRAM)接口,与对方通信时是不需要逻辑连接的。只需要送出一个报文,其地址是一个对方进程所使用的套接字。

因此数据报提供了一个无连接的服务。另一方面,字节流(SOCK_STREAM)要求在交换数据之前,在本地套接字和与之通信的远程套接字之间建立一个逻辑连接。

数据报是一种自包含报文。发送数据报近似于给某人邮寄信件。可以邮寄很多信,但不能保证投递的次序,并且可能有些信件丢失在路上。每封信件包含接收者的地址,使这封信件独立于所有其他信件。每封信件可能送达不同的接收者。

相比之下,使用面向连接的协议通常就像与对方打电话。首先,需要通过电话建立一个连接,连接建立好之后,彼此能双向地通信。每个连接是端到端的通信信道。会话中不包含地址信息,就像呼叫的两端存在一个点对点的虚拟连接,并且连接本身暗含特定的源和目的地。

对于SOCK_STREAM套接字,应用程序意识不到报文界限,因为套接字提供的是字节流服务。这意味着当从套接字读出数据时,它也许不会返回所有由发送者进程所写的字节数。最终可以获得发送过来的所有数据,但也许要通过若干次函数调用得到。

SOCK_SEQPACKET套接字和SOCK_STREAM套接字很类似,但从该套接字得到的是基于报文的服务而不是字节流服务。这意味着从SOCK_SEQPACKET套接字接收的数据量与对方发送的一致。流控制传输协议(Stream Control Transimission Portocol, SCTP)提供了因特网域上的顺序数据包服务。

SOCK_RAW套接字提供一个数据报接口用于直接访问下面的网络层(在因特网域中为IP)。使用这个接口时,应用程序负责构造自己的协议首部,这是因为传输协议(TCP和UDP等)被绕过了。当创建一个原始套接字时需要有超级用户特权,用以防止恶意程序绕过内建安全机制来创建报文。

调用socket与调用open相类似。在两种情况下,均可获得用于输入/输出的文件描述符。当不再需要该文件描述符时,调用close来关闭对文件或套接字的访问,并且释放该描述符以便重新使用。

虽然套接字描述符本质上是一个文件描述符,但不是所有参数为文件描述符的函数都可以接受套接字描述符。表16-3总结了到目前为止所讨论的大多数使用文件描述符的函数处理套接字描述符时的行为。未规定的和由实现定义的行为通常意味着函数不能处理套接字描述符。例如,lseek不处理套接字,因为套接字不支持文件偏移量的概念。

                                            表16-3 使用文件描述符的函数处理套接字时的行为

套接字通信是双向的。可以采用函数shutdown来禁止套接字上的输入/输出。

#include <sys/socket.h>
int shutdown(int sockfd, int how);
返回值:若成功则返回0,出错则返回-1

如果how是SHUT_RD(关闭读端),那么无法从套接字读取数据;如果how是SHUT_WR(关闭写端),那么无法使用套接字发送数据;使用SHUT_RDWR则将同时无法读取和发送数据。

能够使用close关闭套接字,为何还要使用shutdown呢?理由如下:首先,close只有在最后一个活动引用被关闭时才释放网络端点。这意味着如果复制一个套接字(例如采用dup),套接字直到关闭了最后一个引用它的文件描述符之后才会被释放。而shutdown允许使一个套接字处于不活动状态,无论引用它的文件描述符数目多少。其次,有时只关闭套接字双向传输中的一个方向会很方便。例如,如果想让所通信的进程能够确定数据发送何时结束,可以关闭该套接字的写端,然而通过该套接字读端仍可以继续接收数据。

本篇博文内容摘自《UNIX环境高级编程》(第2版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

网络IPC:套接字之套接字描述符的更多相关文章

  1. 网络IPC:套接字之数据传输

    既然将套接字端点表示为文件描述符,那么只要建立连接,就可以使用read和write来通过套接字通信.通过在connect函数里设置对方地址,数据报套接字也可以“连接”.在套接字描述符上采用read和w ...

  2. Linux 进程间通信(二)(网络IPC:套接字)

    socket描述符 套接字是通信端点的抽象,创建一个套接字使用如下函数: #include <sys/socket.h> int socket(int domain, int type, ...

  3. apue学习笔记(第十六章 网络IPC:套接字)

    本章将考察不同计算机(通过网络连接)上的进程相互通信的机制:网络进程间通信. 套接字描述符 正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字. 许多处理文件描述符函数(如read和writ ...

  4. 通过UNIX域套接字传递描述符的应用

      传送文件描述符是高并发网络服务编程的一种常见实现方式.Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现.本文详细说明一下传送文件描述符的应用. 1. TCP服务器程 ...

  5. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  6. 第十六章:网络IPC:套接字

    16.1.引言 上一章考查了各种Unix系统所提供的经典进程间通信(IPC)机制:管道.先进先出.消息队列.信号量以及共享内存.通过这些机制,同一台计算机上运行的进程可以相互通信.本章将考查不同计算机 ...

  7. UNIX网络编程——网络IPC:套接字

    UNIX网络编程——网络IPC:套接字 Contents 套接字接口 套接字描述符 寻址 字节序 地址格式 地址查询 绑定地址 建立连接 数据传输 套接字选项 带外数据 UNIX域套接字 使用套接字的 ...

  8. 网络IPC:套接字

    网络进程间通信(network IPC):不同计算机(通过网络相连)上运行的进程相互通信的机制. 套接字网络IPC接口:进程能够使用该接口和其他进程通信.通过该接口,其他进程运行位置是透明的,它们可以 ...

  9. Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级 ...

  10. UNIX环境高级编程 第16章 网络IPC:套接字

    上一章(15章)中介绍了UNIX系统所提供的多种经典进程间通信机制(IPC):管道PIPE.命名管道FIFO.消息队列Message Queue.信号量Semaphore.共享内存Shared Mem ...

随机推荐

  1. Linux--使用expect进行自动交互

    在linux下进行一些操作时,有时需要与机器进行一些交互操作,比如切换账号时输入账号密码,传输文件时输入账号密码登陆远程机器等,但有时候这些动作需要在shell脚本中进行,这个时候就可以使用expec ...

  2. 《Python基础教程(第二版)》学习笔记 -> 第十章 充电时刻 之 标准库

    SYS sys这个模块让你能够访问与Python解释器联系紧密的变量和函数,下面是一些sys模块中重要的函数和变量: 函数和变量 描述 argv 命令行参数,包括脚本和名称 exit([arg])   ...

  3. C ~ 指针函数与函数指针的区别

    一. 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某 ...

  4. Cadence关闭StartPage的方法

    Cadence 16.5开始,打开原理图工具 Orcad Capture 时,总是会弹出startpage 页面,关闭它的方法: 解决方法如下: (1) View---Toolbar----Comma ...

  5. LeetCode题解——Regular Expression Matching

    题目: 正则表达式的匹配,'.'能匹配任何一个字符,'*'之前必须有一个字符,两个结合起来表示之前那个字符出现0到无穷次. 解法: 一定要注意'*'必须结合前面的字符一起使用. 代码: class S ...

  6. Codevs No.1287 矩阵乘法

    2016-06-01 16:53:23 题目链接: 矩阵乘法 (Codevs No.1287) 题目大意: 给你两个可乘矩阵a,b,求a*b 解法: 定义....... //矩阵乘法 (Codevs ...

  7. 关于put 上传图片的解决方式

    客户端: 因为put只支持单一类型的资源进行传输,所以不能使用像 Multipart/form-data这样的content-type进行描述,而只能使用像image/jpeg .image/png的 ...

  8. 从根源上解析 Java volatile 关键字的实现

    1.解析概览 内存模型的相关概念 并发编程中的三个概念 Java内存模型 深入剖析Volatile关键字 使用volatile关键字的场景 2.内存模型的相关概念 缓存一致性问题.通常称这种被多个线程 ...

  9. JavaScript——对this指针的新理解

    一直以来对this的理解只在可以用,会用,却没有去深究其本质.这次,借着<JavaScript The Good Parts>,作了一次深刻的理解.(所有调试都可以在控制台中看到,浏览器F ...

  10. WinJS.Binding.List与kendo.data.ObservableArray

    avalon0.8一个最大目标是实现对数组的深层监控,可是面临的困难重重,至今还没有什么起色.于是看一下其他两个MVVM框架的做法(knockout, emberjs, angular都不能监听家庭数 ...