网络IPC:套接字之套接字描述符
套接字是通信端点的抽象。与应用程序要使用文件描述符访问文件一样,访问套接字也需要套接字描述符。套接字描述符在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:套接字之套接字描述符的更多相关文章
- 网络IPC:套接字之数据传输
既然将套接字端点表示为文件描述符,那么只要建立连接,就可以使用read和write来通过套接字通信.通过在connect函数里设置对方地址,数据报套接字也可以“连接”.在套接字描述符上采用read和w ...
- Linux 进程间通信(二)(网络IPC:套接字)
socket描述符 套接字是通信端点的抽象,创建一个套接字使用如下函数: #include <sys/socket.h> int socket(int domain, int type, ...
- apue学习笔记(第十六章 网络IPC:套接字)
本章将考察不同计算机(通过网络连接)上的进程相互通信的机制:网络进程间通信. 套接字描述符 正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字. 许多处理文件描述符函数(如read和writ ...
- 通过UNIX域套接字传递描述符的应用
传送文件描述符是高并发网络服务编程的一种常见实现方式.Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现.本文详细说明一下传送文件描述符的应用. 1. TCP服务器程 ...
- (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- 第十六章:网络IPC:套接字
16.1.引言 上一章考查了各种Unix系统所提供的经典进程间通信(IPC)机制:管道.先进先出.消息队列.信号量以及共享内存.通过这些机制,同一台计算机上运行的进程可以相互通信.本章将考查不同计算机 ...
- UNIX网络编程——网络IPC:套接字
UNIX网络编程——网络IPC:套接字 Contents 套接字接口 套接字描述符 寻址 字节序 地址格式 地址查询 绑定地址 建立连接 数据传输 套接字选项 带外数据 UNIX域套接字 使用套接字的 ...
- 网络IPC:套接字
网络进程间通信(network IPC):不同计算机(通过网络相连)上运行的进程相互通信的机制. 套接字网络IPC接口:进程能够使用该接口和其他进程通信.通过该接口,其他进程运行位置是透明的,它们可以 ...
- Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级 ...
- UNIX环境高级编程 第16章 网络IPC:套接字
上一章(15章)中介绍了UNIX系统所提供的多种经典进程间通信机制(IPC):管道PIPE.命名管道FIFO.消息队列Message Queue.信号量Semaphore.共享内存Shared Mem ...
随机推荐
- codedorces 260 div2 A题
水题,扫描一遍看是否出现价格低质量高的情况. #include<cstdio> #include<string> #include<vector> #include ...
- bug报告-常用词汇中英对照表
- Struts2动态调用DMI及错误解决方法
在Strust2中action可以定义自己的方法,调用方法有两种方式,一种方式是struts.xml中指定method来表示需要用到的方法, 但是这种方法缺点在于如果你的Action中有很多方法则要多 ...
- 【windows核心编程】IO完成端口(IOCP)复制文件小例
1.演示内容 文件复制 2.提要 复制大文件时,使用FILE_FLAG_NO_BUFFERING标志 同时需要注意: 读写文件的偏移地址为 磁盘扇区 的整数倍 读写文件的字节数为 磁盘扇区 的整数倍 ...
- CCCallFuncN误用导致引用计数循环引用
昨天测试“角色被遮挡部分透明显示”功能时,发现角色死亡后,其轮廓精灵不会消失.调试发现,角色在死亡时,其引用计数retain_count居然是9.这是由引用计数混乱引起的内存泄露. 加了很多日志跟踪r ...
- python中的类型转换
函数 描述 int(x [,base ]) 将x转换为一个整数 long(x [,base ]) 将x转换为一个长整数 float(x ) 将x转换到一个浮点数 complex(real [,imag ...
- python 常用模块
1.os模块 os模块包装了不同操作系统的通用接口,使用户在不同操作系统下,可以使用相同的函数接口,返回相同结构的结果. os.name:返回当前操作系统名称('posix', 'nt', 'os2' ...
- 1.2……初识Android开发
Android体系结构 Dalvik VM(Android下的java虚拟机)与传统的JVM的区别 传统JVM 基于堆栈的架构 编写.java文件--->编译为.class文件--->打包 ...
- aggregation(2):adaptive Boosting (AdaBoost)
给你这些水果图片,告诉你哪些是苹果.那么现在,让你总结一下哪些是苹果? 1)苹果都是圆的.我们发现,有些苹果不是圆的.有些水果是圆的但不是苹果, 2)其中到这些违反"苹果都是圆的" ...
- USACO 2013 November Contest Gold 简要题解
Problem 1. Empty Stalls 扫两遍即可. Problem 2. Line of Sight 我们发现能互相看见的一对点一定能同时看见粮仓的某一段.于是转换成有n段线段,问有多少对线 ...