欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一起talk C栗子吧(第一百五十一回:C语言实例--socket通信地址)

程序员文章站 2022-03-03 08:37:23
各位看官们,大家好,上一回中咱们说的是socket通信接口的例子,这一回咱们说的是socket通信地址。闲话休提,言归正转。让我们一起talk 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通信地址的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。