【网络编程】OSI开放系统系统互联模型,

TCP和UDP异同(笔试面试)

共同点:同属于传输层的协议,都用于网络传输

TCP ----> 稳定

1> 提供面向连接的,可靠的数据传输服务

2> 传输过程中,数据无误、数据无丢失、数据无失序、数据无重复

        1、TCP会给每个数据包编上编号,该编号称之为序列号

        2、每个序列号都需要应答包应答,如果没有应答,则会将上面的包重复发送直到正确为止

3> 数据传输效率低,耗费资源多

4> 数据收发是不同步的

        1、为了提高效率,TCP会将多个较小,并且发送间隔短的数据包,沾成一个包发送,该现象称为沾包现象

        2、该沾包算法称之为Nagle算法

5> TCP的使用场景:对传输质量比较高的以及传输大量数据的通信,在需要可靠通信的传输场合,一般使用TCP协议

例如:账户登录,大型文件下载的时候

UDP ----> 快速

  1. 面向无连接的,不保证数据可靠的,尽最大努力传输的协议
  2. 数据传输过程中,可能出现数据丢失、重复、失序现象
  3. 数据传输效率高,实时性高
  4. 限制每次传输的数据大小,多出部分直接忽略删除
  5. 收发是同步的,不会沾包
  6. 适用场景:发送小尺寸的,在接收到数据给出应答比较困难的情况下

例如:广播、通讯软件的音视频

网络体系结构及OSI开放系统系统互联模型

网络体系结构概念

每一层都有自己独立的功能,单每一层都不可获取

通常把功能相近的协议组织在一起放在一层,协议栈。所以每一层中其实有多个协议

分层的好处:

1、各层之间独立,每一层不需要知道下一层如何实现,而仅仅只需要知道该层通过层间的接口所提供的服务

2、稳定,灵活性好,当任何一层发生变化时,只需要层间接口关系保持不变,而这层以上或以下层不受影响

3、易于实现和维护(知道是什么功能,就到指定层去查找)

4、促进标准化工作:每一层的功能及其所提供的服务都有了精确的说明。

5、结构上不可分割开:各层都可以采用最合适的技术来实现

字节序

1> 不同主机在存储多字节整数时(short、int、long),由于cpu架构的不同,存储方式也不同,大致分为两类:

大端存储:地址低位存储数据的高位

小端存储:地址低位存储数据的低位

2> 验证方式:使用指针、共用体

#include<myhead.h>

void endian()
{
    int num = 0x12345678;        //定义变量存储多字节整数

    char *ptr = (char *)&num;   //&num是int *类型

    //对地址低位的一字节数据判断
    if(*ptr == 0x12)
    {
        printf("big endian\n");
    }else
    {
        printf("little endian\n");
    }

}




int main(int argc, const char *argv[])
{
    endian();           //调用函数

    return 0;
}

3> 手动将小端存储的数据转换成大端存储的数据

#include<myhead.h>

void endian()
{
    int num = 0x12345678;        //定义变量存储多字节整数

    char *ptr = (char *)&num;   //&num是int *类型

    //对地址低位的一字节数据判断
    if(*ptr == 0x12)
    {
        printf("big endian\n");
    }else
    {
        printf("little endian\n");
    }

    //将数据转变成大端存储的数据
    char *qtr = ptr+3;             //定义指针指向最后一个字节

    //将数据不断进行首尾交换
    while(ptr<qtr)
    {
        char temp = *ptr;
        *ptr = *qtr;
        *qtr = temp;
        ptr++;
        qtr--;
    }

    printf("num = %#x\n", num);         //0x78563412

}




int main(int argc, const char *argv[])
{
    endian();           //调用函数

    return 0;
}

4> 由于主机架构的不同,当一个小端存储的数据发送一个多字节整数时,是没办法确定对方是大端存储还是小端存储的,这样就导致,即使数据无误,传输无误,也会因为存储方式的不同,而导致数据的错误

为了解决上面的问题,我们引入了网络字节序的概念:规定网络字节序是大端存储的字节序列

对于发送端而言,无论是大端存储的主机还是小端存储的主机,向网络中发送多字节整数时,一律改成网络字节序传输;当数据到达对方主机时,无论接收端是大端存储还是小端存储,一律先将接受的数据转变成主机字节序

5> 主机字节序和网络字节序的相互转换函数

主机:host

网络:network

转换:to

    #include <arpa/inet.h>

       uint32_t htonl(uint32_t hostlong);    //将4字节无符号整数的主机字节序转换为网络字节序,参数是主机字节序,返回值是网络字节序

       uint16_t htons(uint16_t hostshort);   //将2字节无符号整数的主机字节序转换为网络字节序,参数是主机字节序,返回值是网络字节序

       uint32_t ntohl(uint32_t netlong);    //将4字节无符号整数的网络字节序转换为主机字节序,参数是网络字节序,返回值是主机字节序

       uint16_t ntohs(uint16_t netshort);     //将2字节无符号整数的网络字节序转换为主机字节序,参数是网络字节序,返回值是主机字节序

例子

#include<myhead.h>

void endian()
{
    int num = 0x12345678;        //定义变量存储多字节整数

    char *ptr = (char *)&num;   //&num是int *类型

    //对地址低位的一字节数据判断
    if(*ptr == 0x12)
    {
        printf("big endian\n");
    }else
    {
        printf("little endian\n");
    }

    /*将数据转变成大端存储的数据
    char *qtr = ptr+3;             //定义指针指向最后一个字节

    //将数据不断进行首尾交换
    while(ptr<qtr)
    {
        char temp = *ptr;
        *ptr = *qtr;
        *qtr = temp;
        ptr++;
        qtr--;
    }

    printf("num = %#x\n", num);         //0x78563412
    */

    //调用函数完成主机字节序转换为网络字节序
    int key = htonl(num);
    printf("key = %#x\n", key);

}




int main(int argc, const char *argv[])
{
    endian();           //调用函数

    return 0;
}

6> 何时使用字节序转换函数

1、在进行网络传输多字节整数时,需要使用字节序转换函数

2、在进行网络传输单字节整数时,不需要使用字节序转换函数

3、在进行网络传输字符串时,不需要使用字节序转换函数

ip地址

1> ip地址的相关概念

1、ip地址全称为(Internet Protocol Address):是主机在网络中的唯一标识。

2、当数据在网络中传输时,需要要携带源ip地址和目的ip地址,路由器就是依靠该地址进行路由选择,以便于确定对端主机的

2> ip地址的分类

1、ipV4:采用的是4字节无符号整数表示,取值范围【0, 2^32-1】

LAN(local area network): 局域网

WAN(Wide Area Network):广域网

2、ipV6:采用16字节无符号整数表示,取值范围【0, 2^128-1】

3> ip地址的分类:ip地址一共分为五类:A、B、C、D、E类网络

A类地址

1.0.0.0~127.255.255.255

2^7(网络号)

2^24(主机号)

已经保留不在供给

B类地址

128.0.0.0~191.255.255.255

2^14

2^16

名地址网管中心

C类地址

192.0.0.0~223.255.255.255

2^21

2^8

校园网或企业网、家庭网

D类地址

224.0.0.0~239.255.255.255

组播地址

E类地址

240.0.0.0~255.255.255.255

保留

4> 一个局域网下的特殊的IP地址

1、网络号 + 0:表示该网络,不分配给任何主机使用

2、网络号 + 255:广播地址,不分配给任何主机使用

3、网络号 + 1:默认为网关地址

4、127.0.0.1:本地环回地址,用于主机内部自测使用

5、0.0.0.0:表示当前局域网的任意一个主机号

6、255.255.255.255:一般表示广播

5> 点分十进制

由于ip地址是一个4字节无符号整数,如果真用整数表示,是一个非常难记忆的数据。为了解决这个问题,我们引入了点分十进制,将4字节的每一个字节为单位转变成十进制数,中间用点隔开。在C语言中,使用字符串存储

由于网络通信中依然使用的是4字节无符号整数,那就需要引入点分十进制与4字节无符号整数转变函数

 #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>



       in_addr_t inet_addr(const char *cp);    //将点分十进制转换为网络字节序,参数是点分十进制,返回值为网络字节序



       char *inet_ntoa(struct in_addr in);    //将网络字节序转换为点分十进制,参数是网络字节序,返回值是点分十进制
#include<myhead.h>

int main(int argc, const char *argv[])
{
    //定义变量存储ip地址
    char *ip = "192.168.0.122";       //主机ip地址

    //调用函数转换为4字节无符号整数
    unsigned int u_ip = inet_addr(ip);

    printf("u_ip = %#x\n", u_ip);    //C0 A8 0 7A

    return 0;
}

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值