Linux 网络基础(1)

本文是《Linux高级程序设计》的读书笔记,更多详细内容大家可以阅读此书

TCP/IP五层(四层)模型


  • TCP/IP是一个协议簇,包含:TCP、IP、UDP、ICMP等多种协议,这些协议一起称为TCP/IP,TCP/IP将网络划分为4层模型。也有奖其划分为五层模型的,但是因为物理层我们考虑的比较少,所以通常按照四层模型来理解
    这里写图片描述

网络接口层:负责数据帧的发送和接收。网络接口层将帧格式的数据放在网络上,或从网络上把帧取下来

网络层:互联协议将数据包封装成IP数据包,并运行必要的路由算法,有效的找到达到目的主机最优的路径。网络层有四种互联协议:

  • 网际协议IP:负责在主机和网络之间路径寻址和路由数据包。目前主要为IPv4地址,IPv6已经在教育网中广泛使用
  • 地址解析协议ARP:获得同一物理网络中的主机硬件地址
  • 网际控制协议ICMP:发送消息,并报告有关数据报的传送错误
  • 互联组管理协议IGMP:用来实现本地多路组播路由器报告

传输层:传输协议在主机之间提供通信会话。传输协议的选择根据数据传输方式而定。主要有以下两个传输协议:

  • 传输控制协议TCP:为应用程序提供可靠的通信连接。适用于一次传输大批数据的情况,并适用于要求得到响应的应用程序
  • 用户数据包协议UDP:提供了无连接通信,且不对传送包进行可靠确认。适合于依稀传输小量数据(一般小于520字节),可靠性则有应用层完成

应用层:应用程序通过这一层访问网络,主要包括常见的FTP、HTTP、DNS和TELNET协议

  • TELNET:提供远程登录服务
  • FTP:提供应用级的文件传输服务
  • SMTP:电子邮件协议
  • SNMP:简单网络管理协议
  • DNS:域名解析服务,将域名映像成IP地址协议
  • HTTP:超文本传输协议,Web服务器所采用的的协议

IPv4协议


在TCP/IP中,主机的MAC地址在物理上唯一的标识了一台主机;IP地址在逻辑上唯一地标识了网络中的某台主机,如果一台主机拥有多个IP地址,则在网络上有多个身份;在主机内部,传输层的端口对应唯一的应用服务。

IP地址

表示形式:主要为点分十进制表示。每个IP地址有两部分组成:网络号和主机号,对IP地址的定义如下:

struct in_addr
{
    _u32 s_addr;        //32bit地址
};
  • 网络ID:同一个网络上所有主机使用同一个网络号,拥有相同网络主机ID并且在物理上连接的主机之间通信不需要路由设备,即他们在一个局域网内
  • 主机ID:确定网络中的一个工作端、服务器、路由器或者其他TCP/IP主机。对于同一个网络号来说,主机号是唯一的。每一个主机有一个逻辑IP地址确定网络号和主机号

网段划分

  • 分为A、B、C、D、E五种类型,可以通过IP地址的前几位来确定网络地址
  • 如下图示:
    这里写图片描述
  • A类地址:网络数为126,最后一个网段127作为本机回环测试,一个子网内允许的主机数太多;0.0.0.0~127.255.255.255
  • B类地址:网络数为16384,一个子网内能允许6万5千多个主机;128.0.0.0~191.255.255.255
  • C类地址:网络数为2097152,一个子网内能允许255个主机;192.0.0.0~223.255.255.255
  • D类地址:被用于组播通信;224.0.0.0~239.255.255.255
  • E类地址:仅供试验;249.0.0.0~247.255.255.255

在分配主机号和网络号时应遵循以下几条规则:

  • 网络号不能为127。该标识号被保留作本地回路及诊断功能
  • 不能将网络号和本机号个位均置为1。若置为1,则被认为是网内广播而不是一个主机号
  • 各位不能均置0,否则该地被认为是本网络
  • 对于本网络来说,主机号必须是唯一的

上述这种网段的划分,是由一定的局限性的,大多数组织都申请B类网络地址,导致B类地址很快被分配完了,而A类却浪费了大量的地址,在上述的划分中,A类和B类理论上一个子网可以允许大量的主机,但是在实际中,不会存在一个子网中有这么多的情况

所以我们提出一种新的划分方案CIDR——引入一个额外的子网掩码来区分网络号和主机号

扫描二维码关注公众号,回复: 931180 查看本文章
子网掩码

我们针对A类这种网络主机太多的情况,提出一种重新管理网络地址的方法,A类主机太多,那么我们就通过划分子网来管理

  • 子网掩码是一个32位的正整数;在子网掩码中,对应IP地址网络号的为都被置为1,所有主机号的位都被置为0
例如C类网IP地址为:192.168.0.1
对应的子网掩码为:255.255.255.0
  • 网络地址可以通过IP地址和子网掩码做与运算得到
192.168.0.1     11000000 00001010 00001010 11000001
//进行与运算
255.255.255.0   11111111 11111111 11111111 00000000
//得到结果(网络号)
192.168.0.0     11000000 00001010 00001010 00000000

划分子网
根据需要划分的子网个数和被划分网络地址,可以确定子网掩码位数,一下是一个C类地址,它是根据需要划分的子网个数来确定子网掩码值:

点分十进制掩码 二进制子网掩码 子网个数
255.255.255.0 11111111 11111111 11111111 00000000 1
255.255.255.128 11111111 11111111 11111111 10000000 2
255.255.255.192 11111111 11111111 11111111 11000000 4
255.255.255.224 11111111 11111111 11111111 11100000 8
255.255.255.240 11111111 11111111 11111111 11110000 16
255.255.255.248 11111111 11111111 11111111 11111000 32
255.255.255.252 11111111 11111111 11111111 11111100 64
  • 我们使用255.255.255.128将C类网络192.10.10.193分成2组子网,各个子网地址、广播地址及可使用的IP地址范围如下所示:
序号 子网地址 广播地址 可使用IP地址范围
1 192.10.10.1 192.10.10.127 192.10.10.2~192.10.10.126
2 192.10.10.128 192.10.10.255 192.10.10.129~192.10.10.254

字节顺序与大小端问题


  • 小端模式:高地址存放高字节
  • 大端模式:高地址存放低字节
  • 在Linux系统下,如果要列出当前系统的字节顺序,可通过一下程序查看:
#include <stdio.h>
#include <endian.h>

int main(void)
{
    printf(" 大端:\t%d \n 小端:\t%d \n mine: \t%d \n",__BIG_ENDIAN,__LITTLE_ENDIAN,__BYTE_ORDER);
    return 0;
}
  • 运行结果如下:
    这里写图片描述
  • 除了上述方法我们可以检测当前系统的字节顺序,还可以利用联合体来检测。联合体存放书序特点:所有成员都从低地址开始申请空间,检测代码如下:
#include <stdio.h>
#include <stdlib.h>

union word
{
    int a;
    char b;
}c;

//(小端) c.a 00 00 00 01  c.b 00
//(大端) c.a 01 00 00 00  c.b 01
int CheckCPU()
{
    c.a = 1;
    return (c.b == 1);
}

int main(void)
{
    int i;
    i=CheckCPU();
    if(i == 0)
        printf("大端\n");
    else if(i == 1)
        printf("小端\n");
    return 0;
}

这里写图片描述

字节顺序转换函数
  • 存储主机信息时,IP地址和端口号存储位网络字节顺序,所以在赋值时需要转换
  • 网络字节顺序为大端,所以网络编程是同一采用大端模式
  • 下面是转换函数声明:
#include <arpa/inet.h>
//n:网络字节序
//h:主机字节序
//l、s:long、short类型
uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);
  • 网络编程中,如果发送纯字符串给对方,则不用特殊处理
  • 如果发送的是多字节数据,则必须转换为大端模式后再发送

猜你喜欢

转载自blog.csdn.net/aurora_pole/article/details/80269582
今日推荐