linux网络编程之socket编程(十五)

今天继续学习socket编程,这次主要是学习UNIX域协议相关的知识,下面开始:

linux网络编程之socket编程(十五)【有个大概的认识,它是来干嘛的】

①、UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍

UNIX域协议主要是用于本地的进程间进行通讯,而TCP的套接字不仅可以用于本地的进程间进行通讯,还可用于两台不同主机上面进程间进行通讯,如果都是用于本地的进程间通讯的话,UNIX域协议比TCP协议效率来得高。

②、UNIX域套接字可以在同一台主机上各进程之间传递描述符。

也就是可以传递一个文件,关于这个知识下一次再学习,稍复杂一些~

③、UNIX域套接字与传统套接字的区别是用路径名来表示协议族的描述。

linux网络编程之socket编程(十五)

linux网络编程之socket编程(十五) 

而对于之前我们用的网际的IPV4的地址结构是sockaddr_in,如下:

linux网络编程之socket编程(十五)

其实结构都差不多,下面,用代码来用UNIX域协议来实现回射客户/服务程序。

linux网络编程之socket编程(十五)

 服务端echosrv.c:

首先创建一个监听套接口:

linux网络编程之socket编程(十五)

在TCP编程中,在正式绑定监听套接字之前是需要设备地址重复利用的,如下:

linux网络编程之socket编程(十五)

而对于UNIX域套接字而言,这一步就不用了,这是与TCP协议不同的,下面则开始绑定:

linux网络编程之socket编程(十五)

接下来则进行监听:

linux网络编程之socket编程(十五)

其中SOMAXCONN是最大连接,可以从listen的man帮助中找到:

linux网络编程之socket编程(十五)

下面则处理客户端发过来的请求,这里简单起见,就用fork进程的方式来处理多个客户端,而不用select方式处理并发了:

linux网络编程之socket编程(十五)

下面来处理客户端的连接:

linux网络编程之socket编程(十五)

另外注意:这里需要引入一个新的头文件:

linux网络编程之socket编程(十五)

下面来编写客户端echocli.c:

首先也是创业套接口:

linux网络编程之socket编程(十五)

接着连接服务器:

linux网络编程之socket编程(十五)

当连接成功之后,就执行回射客户端的函数:

linux网络编程之socket编程(十五)

具体实现基本跟TCP的类似,也比较容易理解:

linux网络编程之socket编程(十五)

下面开始编译运行:

linux网络编程之socket编程(十五)

这也就说明了这句代码的意义,是在bind的时候产生该文件的:

linux网络编程之socket编程(十五)

靠这个文件实现两者的互通,来观察一下它的类型:

linux网络编程之socket编程(十五)

其中可以通过命令来查看linux下的文件类型,其中就有一个套接字文件:

linux网络编程之socket编程(十五)

下面开始运行:

linux网络编程之socket编程(十五)

但是有一个问题,如果我再重新运行服务端:

linux网络编程之socket编程(十五)

如何解决这个问题呢,对于TCP来说可以设置地址重复利用既可,但是对于UNIX域协议来说,可以在重新启动服务端时,将这个路径文件删除既可:

linux网络编程之socket编程(十五)

以就是就是UNIX域协议套接字编程的实现,其实比较简单,下面来看一下它的一些注意点。

linux网络编程之socket编程(十五)

①、bind成功将会创建一个文件,权限为0777 & ~umask

下面来看一下产生的套接字的文件的权限:

linux网络编程之socket编程(十五)

而当前的umask为:

linux网络编程之socket编程(十五)

755=0777 & (~0022)

②、sun_path最好用一个绝对路径

 如果用相对路径会出现什么样的问题呢?下面来做个实验,就是将客户端与服务器程序放到不同的目录里面:

linux网络编程之socket编程(十五)

下面来运行一下:

linux网络编程之socket编程(十五)

所以,为了避免当客户端与服务端程序在不同目录上的问题,可以将文件路径改为绝对的,这里将此文件放到tmp目录中,如下:

linux网络编程之socket编程(十五)

linux网络编程之socket编程(十五)

下面编译之后,再将客户端程序拷贝到上级目录中,让它与服务端不在同一个目录,如下:

linux网络编程之socket编程(十五)

③、UNIX域协议支持流式套接口与报式套接口

基于流式的套接口是需要处理粘包问题,实际上上面写的程序是没有处理粘包问题的,实现思路跟TCP的一样,这里就不演示了;如果是报式套接口就不存在粘包问题。

④、UNIX域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED,这和TCP不同,如果监听队列满,会忽略到来的SYN,这导致对方重传SYN

好了,今天先学到这,下节见~