今天开始,继续来学习linux编程,这次主要是研究下linux下的网络编程,而网络编程中最基本的需从socket编程开始,下面正式开始学习:
什么是socket:
在学习套接口之前,先要回顾一下Tcp/Ip四层模型:

而在说明什么是Socket之前,需要理解下面这些图:

而实际上:

所以:

另外:

这跟管道是不同的,管道只能用于本机的进程间通信。另外socket能用于异构系统间进行通信:

IPv4套接口地址结构:


一般不用

为什么要有地址家族呢?因为Socket不仅仅只能用于Tcp/Ip协议,还能用于其它协议,如:Unix域协议,所以一定得指名是哪个家族,如果是IPv4协议,则需要指定为AF_INET,如果是AF_INET6,则就是IPv6协议,这个用得很少~

16位的无符号整数,也就是两个字节,它能表示的最大的整数为:65535

对于IPv4协议,地址是32位的,也就是四个字节,所以该结构体为无符号的32位整数:


实际上,也可以通过man帮助来看到其结构:man 7 ip

【注意】:平常编程时,只会用到sa_family_t、in_port_t、struct in_addr这三个字段。
通用地址结构:




该字段总共有14个字节,实际上跟sockaddr_in最后面三个字段的总和是一样大小的:

所以说,通用的地址结构可以兼容IPv4的结构
为什么要有通用地址结构呢? 原因在于Socket不仅仅只能用于Tcp/Ip编程,它还能够用于Unix域协议编程,不同的协议地址结构形式可能有不一样的地方,所以说,这里存在一个统一形式的地址结构,可以用于所有的协议编程。
【提示】:实际编程中,通常是填充sockaddr_in地址结构,最终再强制转换成通用的sockaddr地址结构。
网络字节序:
实际上,刚才在查看man帮助时,就出现过这个概念,如:

所以下面来认识一下它:

关于上面的概念,可能有些抽象,下面用图来说明一下:

为什么要引入字节序这样一个概念呢?
这是因为Socket可以用于异构系统之间的通讯,不同的硬件平台,对于一个整数,存放形式是不一样的,有的机器是采用的大端字节序,有的则采用的小端,如果传给对等方可能解析出来的数字就会不一样了,这时就必须统一字节序,这个字节序就叫做“网络字节序”,所以可以看下面介绍。

这里指的就是本机中的实际字节序,下面可以编写一个小小的程序来验证一下我们的机器是什么字节序,如下:


编译运行:


字节序转换函数:

下面来用代码来说明一下:

编译运行:

地址转换函数:
为什么要有地址转换函数呢?因为我们平常人为认识的地址并不是32的数字,我们比较习惯的地址类似于这样:"192.168.0.100",而我们编程的时候,更多的是用的32的数字,所以需要引入地址转换函数,如下:

这个函数的功能跟下面这个函数的功能一样,都是将用户识别的地址转换成网络字节序,将存放在inp这个结构体中,第二个参数是一个输出参数。

将用户识别的类似于"192.168.0.100"这样的地址转换成32位的整数,下面用代码来看一下效果:

编译运行:


将32位的网络字节序转换成我们能识别的ip形式的地址:

编译运行:

套接字类型:

对于TCP/IP协议而言,就是tcp协议,如果是其它协议而言那就不一定了。


它提供了一种能力,让我们跨越传输层,直接对ip层进行数据封装的套接字,通过原始套接字,我们可以将应用层的数据直接封装成ip层能够认识的协议格式,关于原始套接字的编程之后再来学。
好了,关于Socket编码的初步先学到这,下次继续~