一起talk C栗子吧(第一百五十一回:C语言实例--socket通信地址)
各位看官们,大家好,上一回中咱们说的是socket通信接口的例子,这一回咱们说的是socket通信地址。闲话休提,言归正转。让我们一起talk c栗子吧!
看官们,我们使用socket通信时需要知道通信的地址,这好比我们发电子邮件时需要有一个邮件地址一样。其实我们在介绍socket通信接口时就提到过通信地址,只是没有详细介绍而已,当时还有客户提问呢。今天我们将详细介绍socket的通信地址。
socket的通信地址主要是用来标识通信双方,用程序的观点来看,就是用来标识程序中通信的计算机以及其进程。通过通信地址可以知道哪些计算机在进行通信,甚至可以知道计算机中的某个进程在通信。比如数据是从哪个计算机发来的,准备发到哪个计算机中。
我们使用常见的电子邮件做对比,我们可以通过电子邮件的发信人地址知道邮件是由谁发来的,也可以通过收信人地址知道谁会收到邮件。这里的电子邮件地址就好比通信地址,收信人和发信人就好比通信中的计算机。都叫计算机时,大家觉得有点乱,为了方便大家区分计算机,通常情况下,我们把发送数据的计算机叫作客户端,接收数据的计算机叫作服务器。通过通信地址,我们就可以知道客户端和服务器的信息,或者更加确切地说,我们可以知道哪些客户端在和哪些服务器进行通信。
socket的通信地址有固定的格式,就像我们使用的电子邮件地址一样。比如xxx@xxx.com是一个电子邮件地址,该地址中总是使用@符号,该符号前面是邮件名称,后面是邮件服务商的域名。socket的通信地址也有固定的格式,不过通信地址的格式与socket的域有关,不同的通信域有不同的通信地址。接下来我们分别做介绍:
af_unix域的通信地址格式
该类型的通信主要是在同一台计算机的不同进程之间进行通信,因此,通信地址本质上是文件路径,只不过这里说的文件不是普通文件,而是专门用来通信的socket类型的文件。
下面是该类型地址格式的详细定义,该定义位于../include/uapi/linux/un.h
文件中
#define unix_path_max 108 struct sockaddr_un { __kernel_sa_family_t sun_family; /* af_unix */ char sun_path[unix_path_max]; /* pathname */ };
从上面的类型定义中可以看到,该类型是一个结构体类型,结构体包含有两个成员:
sun_family成员表示套接字通信的域; sun_path成员表示文件路径,路径长度定义为108个字符。此外,从该定义中我们也可以看到af_unix域的通信地址是通过文件地址实现的。
af_inet域的通信地址格式
该类型的通信主要是在网络中不同的计算机中之间进行通信,因此,通信地址本质上计算机名和端口号。通过计算机名可以找到计算机,通常我们使用计算机的ip地址而不是计算机名来区分网络中的计算机。
使用端口号是为了给计算机指定一个具体的进程。比如我们通过计算机的80号端口来访问网络,实际上是在使用计算机的web进程和网络服务器中的进程进行通信。总之,对于af_inet域的通信地址来说,我们可以将它的本质归纳为ip地址+端口号。
下面是该类型地址格式的详细定义,该定义位于../include/uapi/linux/in.h
文件中
struct sockaddr_in { __kernel_sa_family_t sin_family; /* address family */ __be16 sin_port; /* port number */ struct in_addr sin_addr; /* internet address */ /* pad to size of `struct sockaddr'. */ unsigned char __pad[__sock_size__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)]; };
从上面的类型定义中可以看到,该类型是一个结构体类型,结构体包含有四个成员:
sun_family成员表示套接字通信的域; sin_addr成员表示计算机的ip地址; sin_port成员表示计算机的端口号; __pad成员表示地址的长度;此外,从该定义中我们也可以看到af_inet域的通信地址在本质上是计算机ip地址和计算机端口号的组合。
通用的通信地址格式
套接字的通信地址也有一个通用的地址格式,它主要是为了把不同的地址格式转换成通用的地址格式,以方便我们在通信接口中使用。下面是该格式的定义,它位于socket.h
文件中:
struct sockaddr { sa_family_t sa_family; /* address family, af_xxx */ char sa_data[14]; /* 14 bytes of protocol address */ };
从上面的定义中可以看到它是一个结构体类型,并且有两个成员:
sa_family成员表示通信的域; sa_data 成员表示通信地址;看官们,我们介绍了这么多关于通信地址的内容,就是为了让大家了解通信地址的格式,当我们在程序中使用通信地址的时候,就能依据通信地址的格式来填写通信地址。当使用套接字通信的时候,我们就可以直接使用已经填写好的通信地址进行通信了。
各位看官,关于socket通信地址的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
推荐阅读
-
一起talk C栗子吧(第一百八十四回:C语言实例--在printf函数中设置输出宽度三)
-
一起talk C栗子吧(第一百九十六回:C语言实例--DIY less命令五 )
-
一起talk C栗子吧(第一百六十二回:C语言实例--套接字知识体系图)
-
一起talk C栗子吧( 第一百四十回:C语言实例--文件操作:基于文件描述符三)
-
一起talk C栗子吧(第一百四十三回:C语言实例--文件操作:基于文件指针三)
-
一起talk C栗子吧(第一百三十九回:C语言实例--文件操作:基于文件描述符二)
-
一起talk C栗子吧(第一百三十八回:C语言实例--文件操作:基于文件描述符一)
-
一起talk C栗子吧(第一百四十一回:C语言实例--文件操作:基于文件指针一)
-
一起talk C栗子吧(第一百四十二回:C语言实例--文件操作:基于文件指针二)
-
一起talk C栗子吧(第一百六十回:C语言实例--套接字通信模型二)