Unix域socket(总结)

来源:互联网 发布:python idle for mac 编辑:程序博客网 时间:2024/05/28 05:17


Unix域协议是在单个主机上执行客户/服务器通信的一种方法,用在本地进程间的通信,在不同进程之间传递套接字。

1)Unix域套接字不需要打包/拆包,计算校验和维护序号与应答,只是将应用层数据从一个进程拷贝到另一个进程,而且Unix域协议机制本质上就是可靠的通讯。

2)Unix套接字可以在同一台主机上各进程之间传递文件描述符。

3)Unix域协议表示协议地址的是路径名,而不是Internet域的IP地址和端口号

 

需注意:

1. bind()成功将会创建一个文件,是一个套接字类型

2. sun_path 最好用一个/tmp目录下的文件的绝对路径,再次启动时最好使用unlink删除这个文件,否则会提示地址正在使用。

3. Unix域协议支持流式套接口与报式套接口

4. Unix域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED

5. 流式套接字需要处理粘包问题。

 

Unix SocketStructure

Sockaddr /sockaddr_in / in_addr / hostent / servent /

客户端通过connect()函数与服务器连接

在一个单处理器计算机上,同一时间只能有一个进程可以运行,其他进程处于等待运行状态。每个进程轮到的运行时间(时间片)相当短暂,给人一种多个程序在同时运行的假象。

 

编写多线程程序时,通过定义宏_REENTRANT来告诉编译器我们需要可重入功能,这个定义必须位于程序中任何#include之前。

Pthread_create创建一个新线程,调用成功时返回0,否则返回错误代码;

线程通过调用pthread_exit()终止调用它的线程并返回一个指向某个对象的指针,注意不能返回局部变量的指针,以免引起严重的程序漏洞。

当从一个进程连接数据流到另一个进程时—管道。把一个进程的输出通过管道连接到另一个进程的输入。

Pipe()参数是一个由两个整数类型的文件描述符组成的数组的指针,数据基于先进先出(FIFO)的原则。从File_descriptor[1]向管道中写数据,再从File_descriptor[0]读回数据。管道有一些内置的缓存区,它在write和read调用之间保存数据。

命名管道(named pipe)

首先服务器应用程序用系统调用socket来创建一个套接字,它是系统分配给该服务器进程的类似文件描述符的资源,不能与其他进程共享。

接下来,服务器进程会给套接字起个名字,本地套接字的名字是Linux系统中的文件名,一般放在/tmp目录中。系统调用bind()来给套接字命名,然后服务器进程就开始等待客户连接到这个命名套接字。系统调用listen创建一个队列并将其用于存放来自客户的进入连接。服务器通过系统调用accept来接受客户的连接。

服务器调用accept时会创建一个与原有的命名套接字不同的新套接字,这个新套接字只用于与这个特定客户进行通信,而命名套接字则被保留下来继续处理来自其他客户的连接。

基于套接字系统的客户端更加简单,客户首先调用accept创建一个未命名套接字,然后将服务器的命名套接字作为一个地址来调用connect与服务器建立连接。一旦连接建立,就可以像使用底层的文件描述符那样用套接字来实现双向的数据通信。

套接字特性由3个属性确定,域(domain)、类型(type)和协议(protocol)

套接字的域指定套接字通信中使用的网络介质,AF_INET指的是Internet网络,许多Linux局域网使用的均是该网络,其底层协议-网络协议(IP)只有一个地址族,它使用一种特定的方式来指定网络中的计算机(IP地址)点分四元组表示法(dotted quad),当客户使用套接字进行跨网络的连接时,它就需要用到服务器计算机的IP地址。客户可以通过IP端口来指定一台联网机器上的某个特定服务。套接字作为通信的终点,必须在开始通信之前绑定一个端口。

服务器在特定的端口等待客户的连接。

AF_UNIX即使是一台还未联网的计算机上的套接字也可以使用这个域,底层协议就是文件输入\输出,地址就是文件名。

套接字类型:流(stream)和数据报(datagram)

流套接字:提供一个有序、可靠、双向字节流的连接。大的数据被分片、传输再重组。接收大量的数据,然后以小数据块的形式将它们写入底层磁盘。发送的数据可以确保不会丢失、复制或乱序到达,并且在这一过程中发生的错误也不会显示出来。SOCK_STREAM

数据报套接字:SOCK_DGRAM 不建立和维持一个连接,对可以发送的数据报和数据报的长度有限制。数据报作为一个单独的网络消息被传输,可能会丢失、复制或乱序到达。从资源角度来看,开销相对较小,因为不需要维持网络连接,而且因为无需花费时间来建立连接,速度比较快。

要想让通过socket调用创建的套接字可以被其他进程使用,服务器程序就必须给该套接字命名。为了能够在套接字上接受进入的连接,服务器程序必须创建一个队列来保存未处理的请求。一旦服务器程序创建并命名了套接字后,它就可以通过accept系统调用来等待客户建立时对该套接字的连接。Accept只有当有客户程序试图连接到由socket参数指定的套接字上时才返回。客户指在套接字队列中排在第一个的未处理连接。Accept将创建一个新的套接字来与该用户进行通信,并且返回该新套接字的描述符。如果套接字队列中没有未处理的连接,accept将阻塞直到有客户建立连接为止。

客户程序通过一个未命名套接字和服务器监听套接字之间建立连接的方法连接服务器connect.

可以通过调用close函数来终止服务器和客户上的套接字连接