we战队穷:Linux Socket学习(一)

来源:百度文库 编辑:中财网 时间:2024/04/29 09:18:10
理解套接口
在我们试着使用套接口之前理解套接口后面的一些内容是很重要的。这一部分描绘出围绕着套接口的一些高级内容。
定义套接口
要与使用电话的某人进行交流,我们必须拿起话筒,拨打对方的电话号码,并且等待对方的应答。当我们与对方通话时,就建立了两个通信端点。
我们的电话,在我们的位置
远方的对方电话,在他的位置。
只要我们仍在通话,就我们之间调用两个端点,建立了一条通信线路。
Linux下的套接口也与电话相类似。套接口代表通信线路中的两个端点。在这两个端点之间存在着数据通信网络。
在另一个方式上,套接口也与电话类似。当我们要打给某人,我们拨打我们要联系的人的电话号码。套接口有网络地址而不是电话号码。通过指定远程套接口地址,我们的程序可以在我们的本地套接口与远程端点之间建立一条通信线路。
由此我们可以推断,一个套接口是通信中的一个端点。有许多的Linux函数调用可以操作套接口,而我们将会慢慢的了解这些。

使用套接口
也许我们会认为Linux套接口很特殊,因为套接口有一个可以在其上进行操作的特定的函数集合。尽管套接口有一些特殊的属性,但是他与我们十分熟悉的文件描述十分相似。
例如,当我们使用Linux的open调用打开一个文件,如果open函数调用成功,我们就会得到一个返回的文件描述符。在我们有了这个文件描述符以后,我们的程序可以使用文件描述符来read,write,lseek,以及close打开的指定文件。相似的,当创建了一个套接口时,他与文件描述符十分想似。我们可以使用相同的文件I/O函数来读,写以及关闭套接口。
然而在套接口与打开的文件之间也存在一些不同。下面列出了其中的一些不同之处:
我们不可以在套接口上执行lseek函数。
套接口有与其相关联的地址。文件和管道没有网络地址。
套接口有可以使用ioctl函数进行查询与设置的不同选项功能。
为了执行输入或输出,套接口必须处理正确的状态。相反,打开的磁盘文件可以在任何时候进行读取或是写入。

引用套接口
当我们使用open函数调用来打开一个新文件时,Linux内核就会返回下一个可用的并且是最小的文件描述符。文件描述符,或者是常称之为文件单元数,是零或者正的整数值,用来引用打开的文件。这个句柄会用在在打开的文件上进行操作的所有函数中。现在我们就会知道文件单元数也可以引用特定的套接口。
我们的程序已经打开了0,1和2三个文件单元(标准输入,标准输出,标准错误),接下来的程序操作将会被执行。注意内核是如何分配文件描述符的:
1 调用open函数来打开一个文件
2 返回文件单元3来引用打开的文件。因为这个单元数当前并没有用,并且是可用的最小的单元数,所以为文件选择了3作为文件单元数。
3 通过一个合适的函数调用来创建一个新的套接口。
4 返回文件单元4来引用这个新的套接口。
5 通过调用open打开另一个文件。
6 返回文件单元5来引用这个新打开的文件。
注意:当分配单元数时,Linux内核在文件与套接口之间并没有区别。用一个文件描述符来引用一个打开的文件或是一个网络套接口。
这就意味着,我们作为一个程序员,可以将套接口当作打开的文件一样来使用。通过文件单元数交互的来引用文件和套接口的能力提供给了我们极大的灵活性。这就意味着read和write函数可以同时在打开的文件和套接口上进行操作。

套接口与管道的比较
在我们介绍任何套接口函数之前,我们来回忆一下我们已经熟悉的pipe函数调用。让我们看一下他返回的文件描述符与套接口的不同。下面是由pipe的手册中得到的函数概要:
#include
int pipe(int filedes[2]);
当这个调用成功时,pipe函数会返回两个文件描述符。数组元素filedes[0]包含管道读端的文件描述符。filedes[1]元素是管道写端的文件描述符。两个文件描述符的这种安排提示了在每一端使用文件描述符的通信连接。这与使用套接口有何不同呢?不同就在于pipe函数创建了一个单向的通信线。信息只可以写入filedes[1]中的文件单元数,并且只可以从filedes[0]中进行读取。任何向相反方向写入数据的尝试都会得到Linux内核返回的错误。
另一个方面,套接口允许在两个方向处理通信。例如,一个进程可以使用在文件单元3上打开的套接口向远端进程发送数据。与使用管道不同,同一个本地进程也可以从文件单元3上接收到与其相通信的远端进程发送的数据。