网络编程(一)基础知识

一、网络简介

(一)网络相关定义

1. 网络协议

协议就是计算机网络中用于设备间相互通信的一系列规则和标准的集合。
这些协议定义了数据交换的格式、信息同步的方式、错误检测与纠正的机制以及数据传输的控制流程等。

2. 网络体系结构

网络体系结构通常采用分层的方式进行设计,每一层都负责处理特定的问题,并通过标准的接口与其他层次进行交互。
它定义了计算机之间相互通信的层次,以及各层中的协议和层次之间接口的集合

3. OSI开放系统互联模型

作用
应用层直接与用户应用程序交互
表示层负责数据的格式化和编码
会话层管理会话的建立、维护和终止,确保数据的有序传输
传输层负责端到端的数据传输,提供可靠的数据传输服务
网络层负责数据包的路由选择和传输路径的确定
数据链路层在物理层提供的原始比特流上建立逻辑链路,确保数据帧的正确传输。处理错误检测和纠正,以及流量控制
物理层处理实际的物理信号传输

OSI开放模型分层过于细致,复杂,会导致效率较慢,因此TCP/IP协议对OSI开放系统模型做了简化
在这里插入图片描述

4. TCP/IP模型

TCP/IP模型通常被描述为四层结构

作用
应用层负责为用户提供服务
传输层负责数据的分段和重组,确保数据的可靠传输。
网络层负责将数据包从源主机传输到目标主机,规定了数据包的传输方式和路由选择。
数据链路层负责将数据帧从物理层传输到网络层,规定了数据帧的格式和传输方式。
(1) 应用层:

HTTP(Hypertext Transfer Protocol) 超文本传输协议
万维网的数据通信的基础,端口号 80

FTP(File Transfer Protocol) 文件传输协议
是用于在网络上进行文件传输的一套标准协议,使用TCP传输,端口号 20/21

TFTP(Trivial File Transfer Protocol) 简单文件传输协议
是用于在网络上进行文件传输的一套标准协议,使用UDP传输,端口号 69

SMTP(Simple Mail Transfer Protocol) 简单邮件传输协议
一种提供可靠且有效的电子邮件传输的协议,端口号 25

(2)传输层:

TCP(Transport Control Protocol) 传输控制协议
是一种面向连接的、可靠的、基于字节流的传输层通信协议

UDP(User Datagram Protocol) 用户数据报协议
是一种无连接、不可靠、快速传输的传输层通信协议

(3)网络层:

IP(Internetworking Protocol) 网际互连协议
是指能够在多个不同网络间实现信息传输的协议

ICMP(Internet Control Message Protocol) 互联网控制信息协议
用于在IP主机、路由器之间传递控制消息----ping命令使用的协议

IGMP(Internet Group Management Protocol) 互联网组管理
是一个组播协议,用于主机和组播路由器之间通信

(4)链路层:

ARP(Address Resolution Protocol) 地址解析协议
通过IP地址获取对方mac地址

RARP(Reverse Address Resolution Protocol) 逆向地址解析协议
通过mac地址获取ip地址

(二)TCP和UDP的异同

1. 连接性

TCP:是面向连接的协议。在数据传输之前,TCP需要进行“三次握手”建立连接;数据传输结束后,还需要通过“四次挥手”来释放连接。
UDP:是无连接的协议。发送方在发送数据之前不需要与接收方建立连接,可以直接发送数据。每个UDP数据包都是独立的,相互之间没有关联。

2. 可靠性

TCP:提供可靠的数据传输服务。通过序列号、确认应答(ACK)机制、重传控制等机制,TCP能够确保数据在传输过程中无差错、不丢失、不重复,并且按序到达。
UDP:不提供可靠的数据传输服务。UDP没有确认应答、重传控制等机制,因此无法确保数据的完整性和顺序性。如果数据包在传输过程中丢失或损坏,UDP不会进行任何恢复操作。

3. 速度和效率

TCP:需要建立连接、进行确认应答和重传控制等操作,在传输效率上相对较低。特别是在网络拥堵时,TCP的拥塞控制机制会进一步降低传输速度。
UDP:没有连接建立和断开的开销,也不需要确认应答和重传控制等机制,因此UDP在传输速度上通常比TCP更快。但是,UDP也可能因为不受拥塞控制的限制而导致网络拥堵。

4. 数据包大小

TCP:在传输数据时,TCP会将数据分割成较小的数据块(称为报文段),并根据网络状况调整数据块的大小。TCP没有固定的数据报大小限制。
UDP:UDP允许发送方一次性将多个数据包打包成一个较大的数据报进行传输。但是,在实际使用中,UDP数据包的大小通常会受到网络传输的最大MTU(最大传输单元)的限制。此外,UDP也没有对数据包进行拆分和重组的机制。

5. 适用场景

TCP:适用于对数据可靠性要求较高的应用场景,如文件传输、电子邮件、网页浏览等。
UDP:适用于对数据实时性要求较高、但对数据可靠性要求不高的应用场景,如音频和视频流传输、在线游戏、实时通信等。

二、网络基础知识

(一)字节序

不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
小端序(little-endian) - 低序字节存储在低地址。
大端序(big-endian)- 高序字节存储在低地址

  • 注:为了保证收发数据的一致性,就发明了网络字节序(大端序) 。发送方发送数据时,需要先把数据转成网络字节序再发送,接收方接到的数据默认都认为是网络字节序的数据,需要转成主机字节序再处理。

1. 实现将四字节无符号整型转为大端字节序功能

#include <stdio.h>
/***第一种判断主机是大端还是小端的方法***/
union _num
{
    int a;
    char b;
};

int if_big_1(void){
    union _num num;
    num.a = 0x12345678;
    return (0x12 == num.b)?1:0;
}
/***第二种判断主机是大端还是小端的方法***/
int if_big_2(void){
    int num = 0x12345678;
    char *p = (char *)&num;
    return (0x12 == *p)?1:0;
}

int my_htonl(int num){
    if(!if_big_1()){
        //如果是小端字节序,需要转成大端字节序
        char *p = (char *)&num;
        char *q = p+3;
        char temp=0;
        //第0位和第3位交换
        temp = *p;
        *p = *q;
        *q = temp;
        //第1位和第2位交换
        p++;
        q--;
        temp = *p;
        *p = *q;
        *q = temp;
    }
    return num;
}

int main(int argc, char const *argv[])
{
    int num = 0x12345678;
    if(!if_big_2()){
        printf("本机为小端存储,%#x-->%#x\n",num, my_htonl(num));
    }else{
        printf("本机为大端存储,%#x-->%#x\n",num, my_htonl(num));
    }
    return 0;
}

2. 系统提供的字节序转换函数

#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字节
// h  host 主机  to  转换  n  network 网络  l  四字节  s 二字节
  • 注:
    1.如果明确知道收发双方的主机字节序一致,可以不考虑字节序问题
    2.多字节的整形序列需要考虑字节序的问题 (字符串可以不考虑)

(二)socket

套接字通信是进程间(而非主机之间)通信的方式的一种。

1. 套接字类型

流式套接字(SOCK_STREAM):提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流式套接字通常使用TCP协议。

数据报套接字(SOCK_DGRAM):提供一种无连接、不可靠的服务。数据报套接字使用UDP协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。

原始套接字(SOCK_RAW):与标准套接字(流套接字和数据报套接字)的区别在于,原始套接字可以读写内核没有处理的IP数据包,而标准套接字只能读取特定协议(TCP或UDP)的数据。原始套接字主要用于一些协议的开发,可以进行比较底层的操作。比如可以对较低层次协议如IP、ICMP直接访问。

(三)IP地址

局域网内部使用MAC地址通信,如果使用互联网,必须用IP地址

1. 手动实现inet_addr函数功能

  • 注:此处使用命令行传参的方式写入点分十进制IP地址,因此其为字符串,所以无需区分主机为大端还是小端。
#include <my_head.h>

int incept_char(char *p,char *str){
    int i=0;
    while('.' != *p&& '\0' != *p){
        str[i]=*(p++);
        i++;    
    }
    return i;//返回.的坐标位置
}

int main(int argc, char const *argv[])
{
    if(2 != argc){
        printf("Usage:%s IPv4\n",argv[0]);
        exit(-1);
    }
    //截取字符串
    char str1[4]={0};
    char str2[4]={0};
    char str3[4]={0};
    char str4[4]={0};
    
    char p[20]={0};
    strcpy(p,argv[1]);

    int i=0,j=0;
    j = incept_char(p,str1);
    i=i+j+1;
    j = incept_char(p+i,str2);
    i=i+j+1;
    j = incept_char(p+i,str3);
    i=i+j+1;
    incept_char(p+i,str4);
    //将截取的字符串转成整型
    int num[4]={0};
    num[0] = atoi(str1);
    num[1] = atoi(str2);
    num[2] = atoi(str3);
    num[3] = atoi(str4);

    //组装成四字节无符号整型数,且为大端    
    unsigned int my_ip=0;
    printf("%ld\n",sizeof(my_ip));
    unsigned char *q = (unsigned char *)&my_ip;
    
    for(int m=0;m<4;m++){
        *(q+m)= *(char*)(num+3-m);
    
    q=(unsigned char *)&my_ip;
    printf("%s --> %d.%d.%d.%d\n", argv[1], q[0], q[1],q[2], q[3]);
    return 0;
}

2. 系统提供的转换函数:

//将点分十进制的字符串 转换成  网络字节序的 无符号四字节整型
in_addr_t inet_addr(const char *cp);

//将网络字节序的无符号四字节整型的ip地址 转换成 点分十进制的字符串
char *inet_ntoa(struct in_addr in);

(四)端口号

端口号是用来标识一个进程,端口号范围[0-65535],usigned short类型,两个字节,在使用时需要区分主机大小端问题

linux系统中 /etc/services 中保存的就是当前系统中已经被占用的端口号
在这里插入图片描述

部分常用服务的端口号:

服务端口号
ftp21
ssh22
tftp69
http80、 8080
mysql3306

三、虚拟机的NAT模式和桥接模式

桥接模式:桥接模式允许虚拟机直接连接到主机的物理网络,就像主机网络上的另一台物理计算机一样。虚拟机与主机就像是完全独立的两台主机,如果想要访问外网,需要有自己的IP地址。

NAT模式:让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。就类似于主机虚拟了一台路由器,虚拟机位于虚拟路由器下的子网中,当虚拟机想要访问公网时,需要使用主机的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值