Day33 网络编程:OSI/TCP/IP模型、协议族与UDP编程

发布于:2025-09-03 ⋅ 阅读:(15) ⋅ 点赞:(0)

day33 网络编程:OSI/TCP/IP模型、协议族与UDP编程

OSI 模型

开放系统互联模型(Open System Interconnect)分为7层,作为理想模型尚未完全实现。各层功能及示例如下:

  • 应用层
    为网络用户提供各种服务(如电子邮件、文件传输)。
    示例:TFTP(简单文件传输协议)用于基础文件操作:
    tftp server get /etc/passwd(二进制模式传输文件)
    tftp server get /etc/123(ASCII模式传输文件)

  • 表示层
    提供统一的数据表示形式,处理加密解密、gzip压缩等数据格式转换。

  • 会话层
    管理进程会话过程(如网络断开时的连接状态维护),通过keep-close/keep-alive机制协调信息传输。

  • 传输层
    管理网络通信两端的数据传输,提供可靠(TCP)或不可靠(UDP)传输服务,适用于文件、视频、音频等数据传输。

  • 网络层
    负责数据传输的路由选择和网际互连,核心协议为IP,支持NAT(网络地址转换)。

  • 数据链路层
    负责物理相邻主机间的数据传输,实现物理地址寻址、数据帧封装和差错控制。该层分为逻辑链路控制子层(LLC)和介质访问控制子层(MAC)。交换机在此层工作,数据以帧格式传输并校验。

  • 物理层
    将主机数据转换成电信号通过网络介质传输,描述通信设备的机械、电气特性。
    示例参数:传输速率(100 Mb/s, 1 Gb/s)、介质类型(双绞线、光纤)、无线频段(2.4 GHz, 5 GHz)。


TCP/IP 模型

网际互联模型分为4层,作为工业标准的实用模型(TCP/IP协议栈):

  • 应用层
    对应应用程序,提供HTTP、FTP等高层服务。
  • 传输层
    涉及端口号,核心协议为TCP(传输控制协议)和UDP(用户数据包)。
  • 网络层
    处理IP地址,核心协议为IP。
  • 接口层
    涉及网卡、驱动,传输速率如1 GB/s;支持pcap(packet capture)技术用于网络数据包捕获分析。

TCP/IP 协议族

包含覆盖网络通信各层的多种协议:

  • 应用层协议
    HTTP、TFTP、FTP、SNMP、DNS等。
    示例:DNS域名解析(www.taobao.com192.168.0.19)。
  • 传输层协议
    TCP、UDP;历史设备示例:56k猫(调制解调器)。
  • 网络层协议
    IP、ICMP(用于ping命令)、RIP、OSPF、IGMP等。
  • 接口层协议
    ARP、RARP等,实现IP地址到MAC地址的映射(ip--->mac)。
ARP 命令示例
arp -a
  • 注释:显示本地ARP缓存表,列出所有IP地址与MAC地址的映射关系。
  • 理想运行结果
    Interface: 192.168.0.100 --- 0x2
      Internet Address      Physical Address      Type
      192.168.0.1           00-11-22-33-44-55     dynamic
      192.160.0.112         aa-bb-cc-dd-ee-ff     dynamic
    
    (注:结果中 192.160.0.112 为示例IP地址,MAC地址为模拟值;实际输出因网络环境而异。)

TCP 编程基础知识

IP 地址分类

IP地址由网络位 + 主机位组成(IPv4点分十进制表示),根据规模分为五类:

类别 IP地址范围 默认子网掩码 私有地址范围 主机数量 典型用途
A类 1.0.0.0 - 126.255.255.255 255.0.0.0 10.0.0.0 - 10.255.255.255 16,777,214 超大规模网络
B类 128.0.0.0 - 191.255.255.255 255.255.0.0 172.16.0.0 - 172.31.255.255 65,534 大中规模网络
C类 192.0.0.0 - 223.255.255.255 255.255.255.0 192.168.0.0 - 192.168.255.255 254 中小规模网络
D类 224.0.0.0 - 239.255.255.255 N/A 组播/广播
E类 240.0.0.0 - 255.255.255.255 N/A 实验用途

关键细节

  • C类网络特性
    • 二进制最高位 110xxxxx
    • 前三组网络地址,第四组主机地址
    • 主机数量 = 254(2^8 - 2,扣除网关和广播地址)
    • 局域网常用私有地址:192.168.x.x
  • 特殊地址
    • 127.0.0.1:本地环回地址(A类保留)
    • 192.168.0.0:网络标识
    • 192.168.0.1:典型网关地址
    • 192.168.0.255:广播地址
  • 单机上网配置流程
    ifconfig ens33 192.168.0.13/24 up  # 设置IP和子网掩码(255.255.255.0)
    route add default gw 192.168.0.1    # 配置默认网关
    echo "nameserver 8.8.8.8" > /etc/resolv.conf  # 设置DNS
    ping www.baidu.com                  # 验证连通性(理想结果:收到ICMP响应)
    netstat -anp                        # 查看网络状态(显示活动连接和端口)
    

网络接口

  • Socket(套接字)
    BSD Socket是网络通信的API接口,本质是应用程序与网络协议栈的桥梁(文件描述符)。
  • IP + Port 机制
    • IP地址:标识主机在网络中的位置
    • 端口号:标识主机上的具体应用程序(范围1-65535)
    • 约定:端口号 < 1000 为系统保留端口
      HTTP: 80      | MySQL: 3306
      FTP: 21       | SSH: 22
      

网络字节序

网络传输采用大端存储(Big-Endian) 格式(高位字节在前),需通过转换函数确保数据一致性:

数字转换函数(#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);  // 主机字节序 → 网络字节序(32位)
uint16_t htons(uint16_t hostshort); // 主机字节序 → 网络字节序(16位)
uint32_t ntohl(uint32_t netlong);   // 网络字节序 → 主机字节序(32位)
uint16_t ntohs(uint16_t netshort);  // 网络字节序 → 主机字节序(16位)
  • 理想运行结果
    htonl(0x12345678) 返回 0x78563412(大端格式)

UDP 编程

UDP 特性

  • 无连接
  • 不可靠(可能丢包)
  • 低延迟
  • 网络开销小
  • 适用于实时性要求高的场景(如视频直播、在线游戏)

UDP 通信框架

C/S模式通信流程:

在这里插入图片描述

客户端流程

  1. 创建套接字:fd = socket()
  2. 发送/接收数据(循环):
    • sendto(fd, buf, size, addr) 发送数据
    • recvfrom(fd, buf, size, addr) 接收应答
  3. 关闭套接字:close(fd)

服务器流程

  1. 创建套接字:fd = socket()
  2. 绑定地址:bind(fd, 服务器地址端口)
  3. 接收/发送数据(循环):
    • recvfrom(fd, buf, size, addr) 接收请求
    • sendto(connfd, buf, size, addr) 发送应答

关键函数说明

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
  • 功能:UDP协议中向对方发送数据
  • 参数
    • sockfd:本地套接字ID
    • buf:发送数据缓冲区
    • len:数据长度
    • flags:发送方式(0=阻塞)
    • dest_addr:目标主机地址结构体(必选)
    • addrlen:目标地址长度
  • 返回值:成功返回发送字节数,失败返回-1
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
  • 功能:UDP协议中接收对方数据
  • 参数
    • sockfd:本地套接字ID
    • buf:接收数据缓冲区
    • len:缓冲区大小
    • flags:接收方式(0=阻塞)
    • src_addr:对方地址结构体(可选,NULL表示不关心)
    • addrlen:对方地址长度指针
  • 返回值:成功返回接收字节数,失败返回-1

注意

  • socket(PF_INET, SOCK_DGRAM, 0) 创建UDP套接字
  • bind() 服务器端必须调用,客户端可选

UDP 服务器代码示例

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>

typedef struct sockaddr * (SA);  // 定义sockaddr指针别名
int main(int argc, char **argv)
{
  // 创建UDP套接字
  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (-1 == sockfd)
  {
    perror("socket");  // 打印错误信息
    return 1;
  }

  // 配置服务器地址结构
  struct sockaddr_in ser, cli;
  ser.sin_family = AF_INET;       // IPv4协议族
  ser.sin_port = htons(50000);    // 主机转网络字节序端口
  ser.sin_addr.s_addr = inet_addr("192.168.14.128");  // 设置IP地址

  // 绑定套接字到指定地址
  int ret = bind(sockfd, (SA) &ser, sizeof(ser));
  if (-1 == ret)
  {
    perror("bind");  // 绑定失败处理
    return 1;
  }

  time_t tm;
  socklen_t len = sizeof(cli);
  while (1)  // 持续服务循环
  {
    char buf[512] = {0};  // 接收缓冲区
    time(&tm);  // 获取当前时间
    // 接收客户端数据(阻塞等待)
    recvfrom(sockfd, buf, sizeof(buf), 0, (SA)&cli, &len);
    // 附加时间戳到消息
    sprintf(buf, "%s %s", buf, ctime(&tm));
    // 将处理后的消息回传客户端
    sendto(sockfd, buf, strlen(buf), 0, (SA)&cli, len);
  }

  return 0;  // 理想结果:持续运行并处理客户端请求
}

UDP 客户端代码示例

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

typedef struct sockaddr * (SA);  // 定义sockaddr指针别名
int main(int argc, char **argv)
{
  // 创建UDP套接字
  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (-1 == sockfd)
  {
    perror("socket");  // 错误处理
    return 1;
  }
  
  // 配置服务器地址结构
  struct sockaddr_in ser;
  ser.sin_family = AF_INET;       // IPv4协议族
  ser.sin_port = htons(50000);    // 主机转网络字节序端口
  ser.sin_addr.s_addr = inet_addr("192.168.14.128");  // 服务器IP

  int i = 10;
  while (i--)  // 发送10次请求
  {
    char buf[512] = "hello,this udp test";  // 初始化消息
    // 发送数据到服务器
    sendto(sockfd, buf, strlen(buf), 0, (SA)&ser, sizeof(ser));
    bzero(buf, sizeof(buf));  // 清空缓冲区
    // 接收服务器响应(阻塞等待)
    recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
    printf("from ser:%s\n", buf);  // 打印服务器响应
    sleep(1);  // 间隔1秒
  }
  close(sockfd);  // 关闭套接字

  return 0;  // 理想结果:输出10次类似 "from ser:hello,this udp test Wed Jun 12 10:30:45 2024"
}

核心知识点整合

网络模型对比

OSI模型 TCP/IP模型 核心功能
应用层 应用层 提供用户服务(HTTP/FTP/DNS等)
表示层 数据格式转换(加密/压缩)
会话层 管理会话状态(keep-alive)
传输层 传输层 端到端通信(TCP/UDP)
网络层 网络层 路由选择(IP协议)
数据链路层 接口层 帧传输/错误控制(ARP/交换机)
物理层 电信号传输

网络诊断命令

命令 功能 典型输出
arp -a 显示ARP缓存表 IP-MAC映射列表
ifconfig 查看网卡配置 IP地址、子网掩码、MAC地址等
ping 测试网络连通性 “64 bytes from 8.8.8.8: icmp_seq=1 ttl=56”
netstat -anp 查看活动网络连接 TCP 0.0.0.0:22 0.0.0.0:* LISTEN sshd

传输层协议对比

特性 TCP UDP
连接方式 面向连接(三次握手) 无连接
可靠性 可靠传输(确认重传机制) 不可靠(可能丢包)
传输速度 较慢
适用场景 文件传输、网页浏览 视频直播、在线游戏
典型端口 HTTP(80)、SSH(22) DNS(53)、DHCP(67)

网站公告

今日签到

点亮在社区的每一天
去签到