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

Posted talk_8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起talk C栗子吧(第一百五十一回:C语言实例--socket通信地址)相关的知识,希望对你有一定的参考价值。


各位看官们,大家好,上一回中咱们说的是socket通信接口的例子,这一回咱们说的是socket通信地址。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,我们使用socket通信时需要知道通信的地址,这好比我们发电子邮件时需要有一个邮件地址一样。其实我们在介绍socket通信接口时就提到过通信地址,只是没有详细介绍而已,当时还有客户提问呢。今天我们将详细介绍socket的通信地址。

socket的通信地址主要是用来标识通信双方,用程序的观点来看,就是用来标识程序中通信的计算机以及其进程。通过通信地址可以知道哪些计算机在进行通信,甚至可以知道计算机中的某个进程在通信。比如数据是从哪个计算机发来的,准备发到哪个计算机中。

我们使用常见的电子邮件做对比,我们可以通过电子邮件的发信人地址知道邮件是由谁发来的,也可以通过收信人地址知道谁会收到邮件。这里的电子邮件地址就好比通信地址,收信人和发信人就好比通信中的计算机。都叫计算机时,大家觉得有点乱,为了方便大家区分计算机,通常情况下,我们把发送数据的计算机叫作客户端,接收数据的计算机叫作服务器。通过通信地址,我们就可以知道客户端和服务器的信息,或者更加确切地说,我们可以知道哪些客户端在和哪些服务器进行通信。

socket的通信地址有固定的格式,就像我们使用的电子邮件地址一样。比如[email protected]是一个电子邮件地址,该地址中总是使用@符号,该符号前面是邮件名称,后面是邮件服务商的域名。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语言实例--socket通信地址)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

一起talk C栗子吧(第一百五十二回:C语言实例--计算机中的大小端)

一起talk C栗子吧(第一百五十六回:C语言实例--基于AF_UNIX域的流套接字通信)

一起talk C栗子吧(第一百五十八回:C语言实例--基于AF_INET域的流套接字通信)

一起talk C栗子吧(第一百五十七回:C语言实例--基于AF_UNIX域的数据报套接字通信)