网络编程第一天学习笔记(重点:UDP 协议)

一、网络通信模型

1. OSI (Open System Interconnect)七层模型(自上而下)

层级 核心功能 典型协议 / 技术
应用层 为应用程序提供网络服务(直接面向用户) HTTP、FTP、DNS、DHCP
表示层 数据编码 / 解码、加密 / 解密、压缩 / 解压缩,统一数据格式 ASCII、JPEG、SSL
会话层 建立、管理、终止应用程序间的通信会话 RPC、NetBIOS
传输层 端到端数据传输,定义端口,提供可靠 / 不可靠传输 TCP、UDP
网络层 IP 地址分配、路由选择,实现跨网络数据传输 IP、RIP、OSPF、ARP
数据链路层 MAC 地址封装 / 解封装,帧传输、差错检测 Ethernet、PPP
物理层 将数据转为电 / 光信号,定义物理介质接口(网线、光纤等) 双绞线、光纤、网卡

2. TCP/IP 模型(实际应用 4 层模型)

层级 对应 OSI 层级 核心功能
应用层 应用层 + 表示层 + 会话层 提供各类网络应用服务
传输层 传输层 TCP/UDP 协议实现端到端传输
网际层(网络层) 网络层 IP 地址、路由选择
网络接口层 数据链路层 + 物理层 物理传输、MAC 地址处理

二、核心网络名词解释

名词 全称 核心功能 所属层级
DNS 域名系统(Domain Name System) 将域名(如www.baidu.com)解析为 IP 地址,解决 IP 难记问题 应用层
DHCP 动态主机配置协议 自动分配 IP 地址、子网掩码、网关、DNS 服务器等网络配置 应用层
TCP 传输控制协议 面向连接、可靠、面向字节流的传输协议(明日重点学) 传输层
RIP 路由信息协议 基于距离矢量算法的内部网关协议,最大跳数 15,适用于小型网络 网络层
OSPF 开放式最短路径优先协议 基于链路状态算法的内部网关协议,高效稳定,适用于大型网络 网络层
ARP 地址解析协议 将 IP 地址转换为 MAC 地址,实现同一局域网内通信 网络层

三、网络基础

1. IP 地址分类(IPv4)

类别 地址范围 网络位 / 主机位 默认子网掩码 适用场景
A 类 1.0.0.0~126.255.255.255 8 位 / 24 位 255.0.0.0 大型网络(运营商、大企业)
B 类 128.0.0.0~191.255.255.255 16 位 / 16 位 255.255.0.0 中型网络(学校、中型企业)
C 类 192.0.0.0~223.255.255.255 24 位 / 8 位 255.255.255.0 小型网络(家庭、小公司)
D 类 224.0.0.0~239.255.255.255 无主机位 - 组播(视频会议等)
E 类 240.0.0.0~255.255.255.255 无主机位 - 科研实验(保留未商用)

2. 常用 Linux 网络指令

指令 核心功能
sudo reboot 重启系统(需管理员权限),网络配置修改后生效
ifconfig 查看 / 配置网络接口(IP、MAC、子网掩码),如ifconfig eth0 192.168.1.100
ping 目标 IP / 域名 测试网络连通性,如ping -c 4 192.168.1.1(发送 4 个数据包后停止)
ip addr 替代 ifconfig,查看更全面的网络接口信息
netstat -tuln 查看所有监听的 TCP/UDP 端口(-t:TCP,-u:UDP,-l: 监听,-n: 不解析域名)
route -n 查看路由表(-n: 不解析域名,速度更快)
arp -a 查看 ARP 缓存表(IP 与 MAC 映射关系)
nslookup 域名 测试 DNS 解析,如nslookup www.baidu.com
sudo ifdown/ifup eth0 关闭 / 启用指定网卡(如 eth0)

四、网络编程基础概念

1. Socket 套接字

  • 定义:应用程序与网络协议栈的交互接口,本质是 Linux 下的文件描述符,实现跨主机通信。
  • 分类:
    • SOCK_STREAM:流式套接字,对应 TCP 协议(可靠连接);
    • SOCK_DGRAM:数据报套接字,对应 UDP 协议(无连接);
    • SOCK_RAW:原始套接字,用于底层协议开发(如抓包)。

2. 网络字节序

  • 大端字节序(网络字节序):高位字节存低地址(网络传输统一标准);
  • 小端字节序(主机字节序):低位字节存低地址(多数主机默认);
  • 转换函数:
    • htons ():主机字节序→网络字节序(16 位,端口号转换);
    • htonl ():主机字节序→网络字节序(32 位,IP 地址转换);
    • ntohs ()/ntohl ():网络字节序→主机字节序(对应上述反向转换)。

五、核心重点:UDP 协议

1. UDP 协议特征

  • 无连接:通信前无需建立连接,直接发送数据,无需确认对方在线;
  • 不可靠:不保证数据有序 / 完整,可能丢失、重复、乱序,无确认机制;
  • 面向数据报:数据以 "数据报" 为单位传输,单包最大 65535 字节;
  • 速度快:协议开销小,无握手 / 确认流程,实时性高;
  • 支持广播 / 组播:可向多个主机同时发送数据(TCP 仅点对点);
  • 适用场景:视频通话、语音聊天、DNS 查询、游戏数据传输等。

2. UDP 通信流程

(1)服务器端流程
复制代码
创建套接字(socket())→ 绑定地址/端口(bind())→ 循环接收/响应(recvfrom()/sendto())→ 关闭套接字(close())
(2)客户端流程
复制代码
创建套接字(socket())→ 循环发送/接收(sendto()/recvfrom())→ 关闭套接字(close())

(注:客户端无需绑定端口,系统自动分配随机端口)

3. UDP 核心函数详解

(1)socket () - 创建套接字
  • 原型:int socket(int domain, int type, int protocol);
  • 功能:创建套接字,返回文件描述符;
  • 参数:
    • domain:协议域,AF_INET(IPv4)、AF_INET6(IPv6);
    • type:套接字类型,SOCK_DGRAM(UDP)、SOCK_STREAM(TCP);
    • protocol:协议类型,UDP 填 0(自动匹配);
  • 返回值:成功返回非负文件描述符,失败返回 - 1(设置 errno)。
(2)bind () - 绑定地址与端口
  • 原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 功能:将套接字绑定到指定 IP 和端口;
  • 参数:
    • sockfd:socket () 返回的文件描述符;

    • addr:通用地址结构体,实际用 struct sockaddr_in(IPv4),需强制转换:

      复制代码
      struct sockaddr_in {
          sa_family_t sin_family; // 协议族,AF_INET
          in_port_t sin_port;     // 端口号,需htons()转换为网络字节序
          struct in_addr sin_addr; // IP地址,INADDR_ANY表示绑定本机所有IP
      };
    • addrlen:地址结构体长度,sizeof (struct sockaddr_in);

  • 返回值:成功返回 0,失败返回 - 1(设置 errno)。
(3)recvfrom () - 接收 UDP 数据
  • 原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
  • 功能:接收 UDP 数据,并获取发送方地址;
  • 参数:
    • sockfd:套接字文件描述符;
    • buf:接收数据的缓冲区;
    • len:缓冲区大小;
    • flags:接收标志,0(阻塞接收)、MSG_DONTWAIT(非阻塞);
    • src_addr:输出参数,存储发送方(客户端)地址,客户端接收数据时就填NULL,因为肯定是刚才访问的服务器发来的;
    • addrlen:输入输出参数,传入 src_addr 长度,返回实际地址长度;
  • 返回值:成功返回接收字节数,失败返回 - 1(设置 errno)。
(4)sendto () - 发送 UDP 数据
  • 原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
  • 功能:向指定目标地址发送 UDP 数据;
  • 参数:
    • sockfd:套接字文件描述符;
    • buf:待发送数据缓冲区;
    • len:发送数据长度(≤65535 字节);
    • flags:发送标志,0(默认);
    • dest_addr:目标主机(服务器 / 客户端)地址结构体;
    • addrlen:目标地址结构体长度;
  • 返回值:成功返回发送字节数,失败返回 - 1(设置 errno)。
(5)close () - 关闭套接字
  • 原型:int close(int fd);
  • 功能:释放套接字资源;
  • 参数:fd:套接字文件描述符;
  • 返回值:成功返回 0,失败返回 - 1(设置 errno)。

服务端代码:

cs 复制代码
// server 服务端
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
//起别名
typedef struct sockaddr * (SA);
int main(int argc, char **argv)
{
    // 1.创建套接字:internet,udp,默认协议
    int udpfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == udpfd)
    {
        perror("socket");
        return 1;
    }
    // 2. 给套接字 绑定ip ,端口号
    // 定义服务器的地址结构体, 客户端的地址结构体
    struct sockaddr_in ser, cli;  

    //结构体清零
    bzero(&ser, sizeof(ser));
    bzero(&cli, sizeof(cli));

    //完善结构体
    ser.sin_family = AF_INET;     // ipv4
    ser.sin_port = htons(50000);  // port端口号:小端转大端
    ser.sin_addr.s_addr = inet_addr("192.168.31.136");//ip地址
    
    //bind绑定ip
    int ret = bind(udpfd, (SA)&ser, sizeof(ser));
    if (-1 == ret)
    {
        perror("bind");
        return 1;
    }

    //客户端地址结构体大小
    socklen_t len = sizeof(cli);
    //循环:接收-发送
    while (1)
    {   
        //定义缓冲区接收数据
        char buf[1024]={0};
        //接收cli发的数据
        recvfrom(udpfd,buf,sizeof(buf),0,(SA)&cli,&len);
        time_t tm;
        time(&tm);
        //拼接要发送的内容
        sprintf(buf,"%s %s",buf,ctime(&tm));
        //发送数据
        sendto(udpfd,buf,strlen(buf),0,(SA)&cli,len);
    }
    return 0;
}

客户端代码:

cs 复制代码
// client 客户端
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>

//起别名
typedef struct sockaddr *(SA);

int main(int argc, char **argv)
{
    // 1.创建套接字 internet , udp, 默认协议
    int udpfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == udpfd)
    {
        perror("socket");
        return 1;
    }

    //服务器的地址结构体
    struct sockaddr_in ser;  
    bzero(&ser, sizeof(ser));
    ser.sin_family = AF_INET;     // ipv4
    ser.sin_port = htons(50000);  // host to net short 小端转大端
    ser.sin_addr.s_addr = inet_addr("192.168.31.177");

    //循环:发送-接收
    while (1)
    {
        char buf[1024] = "hello,this is why test";

        //客户端-发送数据
        sendto(udpfd, buf, strlen(buf), 0, (SA)&ser, sizeof(ser));
        bzero(buf, sizeof(buf));
        
        //接收ser发的数据
        recvfrom(udpfd, buf, sizeof(buf), 0, NULL, NULL);

        printf("from ser:%s\n", buf);
        sleep(1);
    }
    //关闭套接字
    close(udpfd);
    return 0;
}

六、今日学习总结

  1. 掌握 OSI/TCP/IP 分层模型,理解各层核心功能,是网络编程的基础;
  2. 熟悉 IP 地址分类、常用网络指令,能完成基础网络配置与测试;
  3. 理解 Socket 套接字、网络字节序的核心概念,解决跨主机数据传输格式问题;
  4. 重点掌握 UDP 协议的无连接、不可靠、面向数据报特征,以及 UDP 客户端 / 服务器通信流程;
  5. 熟记 UDP 核心函数(socket ()/bind ()/recvfrom ()/sendto ())的原型、参数、返回值,为编写 UDP 程序打下基础。
相关推荐
非凡ghost2 小时前
proDAD ReSpeedr:专业视频变速编辑的利器
java·网络·windows·python·音视频·软件需求
路溪非溪2 小时前
Linux下iw工具的使用总结
linux·网络·arm开发·驱动开发
大榕树信息科技2 小时前
高效动环监控赋能机房环境智能管理与数据可视化
大数据·网络·数据库·人工智能·信息可视化
GlobalInfo3 小时前
全球户外WiFi智能插头市场份额、规模、技术研究报告2026
大数据·网络·人工智能
姜太小白3 小时前
【SQLServer】SQL Server 2022 连接证书错误解决
网络·数据库·sqlserver
゛anqiaoyun3 小时前
WebSocket告警无声音
网络·websocket·网络协议
Ka1Yan3 小时前
RPC核心原理:组件与调用流程
网络·网络协议·rpc
大罗辑3 小时前
2026软考【系统分析师】考试:核心知识考点汇总(二)
网络·系统分析师·2026软考考试·软考系统分析师·系统分析师考试重点·系分资料·系统分析师题库
历程里程碑3 小时前
39. 从零实现UDP服务器实战(带源码) V1版本 - Echo server
服务器·开发语言·网络·c++·网络协议·udp·php