Linux 套接字与文件描述符
Posted 庖丁解牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 套接字与文件描述符相关的知识,希望对你有一定的参考价值。
端口和套接字,用于确定指定主机上的哪个本地进程使用了哪个协议和哪台远程主机上的哪个进程进行了通信。端口和套接字的使用可以基于以下几点: ①为每个应用过程分配一个过程标识符(Process ID),每次启动一个进程时,这个ID都可能是不同的。 ②进程ID因操作系统平台不同而不同,因而它们是不统一的。 ③一个服务器过程能够同时与多个客户连接,因而简单的连接标识符不可能是唯一的。 端口和套接字概念提供了一种以统一的方式唯一地标识连接以及参与连接的程序和主机的方法,而不管特定的过程ID。 (1)端口 网络中可以被命名和寻址的通信端口,是操作系统可分配的一种资源。 按照OSI七层协议的描述,传输层与网络层在功能上的最大区别是传输层提供进程通信能力。 从这个意义上讲,网络通信的最终地址就不仅仅是主机地址了,还包括可以描述进程的某种标识符。 为此,TCP/IP协议提出了协议端口(protocol port,简称端口)的概念,用于标识通信的进程。 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。 应用程序(即进程)通过系统调用与某端口建立连接(binding)后, 传输层传给该端口的数据都被相应进程所接收,相应进程发给传输层的数据都通过该端口输出。 在TCP/IP协议的实现中,端口的操作类似于一般的I/O操作,进程获取一个端口, 相当于获取本地唯一的I/O文件,可以用一般的读写原语访问之。 类似于文件描述符,每个端口都拥有一个叫端口号(port number)的整数型标识符, 用于区别不同端口。由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块, 因此各自的端口号也相互独立,如TCP有一个255号端口,UDP也可以有一个255号端口,二者并不冲突。 端口号的分配 端口号的分配是一个重要问题。有两种基本分配方式: 第一种叫全局分配,这是一种集中控制方式,由一个公认的中央机构根据用户需要进行统一分配,并将结果公布于众。 第二种是本地分配,又称动态连接,即进程需要访问传输层服务时,向本地操作系统提出申请,操作系统返回一个本地唯一的端口号, 进程再通过合适的系统调用将自己与该端口号联系起来(绑扎)。TCP/IP端口号的分配中综合了上述两种方式。 端口被划分为以下3段。 1)众所周知的端口为0~1023.这些端口由IANA分配和控制。可能的话,相同端口号就分配给TCP、UDP和SCTP的同一给定服务。 例如,不论TCP还是UDP端口号80都被赋予Web服务器,尽管它目前的所有实现都单纯使用TCP。 2)已登记的端口为1024~49151.这些端口不受IANA控制,不过由IANA登记并提供它们的使用情况清单,以方便整个群众。 可能的话,相同端口号也分配给TCP和UDP的同一给定服务。 3)49152~65535是动态的或私用的端口。IANA不管这些端口。它们就是我们所称的临时端口。 知名端口即众所周知的端口号,范围从0到1023,这 些端口号一般固定分配给一些服务。比如20/21端口分配给FTP(文件传输协议)服务, 23端口分配给Telnet(远程登录),25端口分配给SMTP(简单邮件传输协议)服务,8 0端口分配给HTTP服务,135端口分配给RPC(远程过程调用)服务等等。 网络服务是可以使用其他端口号的,如 果不是默认的端口号则应该在地址栏上指定端口号,方法是在地址后面加上冒号“:”(半角),再加上端口 号。 比如使用“8080”作为WWW服务的端口,则需要在地址栏里输入“:8080”。 但是有些系统协议使用固定的端口号,它是不能被改变的,比如139 端口专门用于NetBios与TCP/IP之间的通信,不能手动改变。 不过,动态端口也常常被病毒木马程序所利用,如冰河默认连接端口是7626、WAY 2.4是8011、Netspy 3.0是7306、YAI病毒是1024等 。 (2)套接字 套接字存在于通信区域中,通信区域也叫地址族,它是一个抽象的概念,主要用于将通过套接字通信的进程的共有特性综合在一起。 套接字通常只与同一区域的套接字交换数据(也有可能跨区域通信,但这只在执行了某种转换进程后才能实现)。 Windows Sockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议族通信的进程使用。 分类: 常用的TCP/IP协议的3种套接字类型如下所示。 流套接字(SOCK_STREAM): 流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送, 并按顺序接收(数据在传送过程中顺序可能会发生变化,但是接收端最后是按顺序接收的)。 流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。 数据报套接字(SOCK_DGRAM): 数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复, 且无法保证顺序地接收到数据。数据报套接字使用UDP(User Datagram Protocol)协议进行数据的传输。 由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。 原始套接字(SOCK_RAW): 原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于: 原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据, 数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。 通信: 使用套接字进行数据处理有两种基本模式:同步和异步。 同步模式:同步模式的特点是在通过Socket进行连接、接收、发送数据时, 客户机和服务器在接收到对方响应前会处于阻塞状态,即一直等到收到对方请求进才继续执行下面的语句。 可见,同步模式只适用于数据处理不太多的场合。当程序执行的任务很多时,长时间的等待可能会让用户无法忍受。 异步模式:异步模式的特点是在通过Socket进行连接、接收、发送操作时, 客户机或服务器不会处于阻塞方式,而是利用callback机制进行连接、接收、发送处理, 这样就可以在调用发送或接收的方法后直接返回,并继续执行下面的程序。可见,异步套接字特别适用于进行大量数据处理的场合。 使用同步套接字进行编程比较简单,而异步套接字编程则比较复杂。 一个TCP连接的套接字对是一个定义该连接的两个端点的四元组:本地IP地址、本地TCP端口号、外地IP地址、外地TCP端口号。 套接字对唯一标识一个网络上的每个TCP连接。 就SCTP而言,一个关联由一组本地IP地址、一个本地端口、一组外地IP地址、一个外地端口标识。 在两个端点均非多宿这一最简单的情形下,SCTP与TCP所用的四元组套接字对一致。 然而在某个关联的任何一个端点为多宿的情形下,同一关联可能需要多个。
以上是关于Linux 套接字与文件描述符的主要内容,如果未能解决你的问题,请参考以下文章