嵌入式——Linux软件编程——网络1

【Linux C学习笔记】4.4 网络编程基础学习总结

📖今日学习:OSI七层模型、TCP/IP四层模型、IP地址分类、虚拟机网络模式、字节序转换、socket套接字、UDP编程、TCP编程。

🔍文章大纲

  1. 网络基础概念
  2. OSI七层模型与TCP/IP四层模型
  3. IP地址、子网掩码、IP地址分类
  4. 虚拟机网络模式(NAT / 桥接模式)
  5. 网络字节序(大端、小端)转换函数
  6. UDP套接字编程(socket、sendto、recvfrom、bind)
  7. TCP套接字编程(socket、connect、listen、accept、send、recv)
  8. ✨学习重点汇总
  9. ⚠️易错点&踩坑记录
  10. 📝今日学习小结

1. 网络基础概念

协议:通信双方预先约定好的一套通信标准,规定数据格式、交互规则。

OSI七层参考模型

层级 名称 作用
7 应用层 业务数据内容
6 表示层 数据加密、解密、格式转换
5 会话层 建立/维持会话连接
4 传输层 负责端到端传输(TCP/UDP)
3 网络层 路由选择,IP寻址
2 数据链路层 局域网MAC帧传输
1 物理层 网线、网卡等硬件电气信号

TCP/IP四层实际模型(Linux网络编程使用)

层级 包含协议
应用层 HTTP、HTTPS、FTP、DNS、TFTP、SMTP
传输层 TCP、UDP
网络层 IP、ARP、RARP
网络接口层 网卡驱动、MAC通信
  • UDP:无连接,不可靠,资源开销小,只管发送,不确认对方是否收到。
  • TCP:面向连接,可靠传输;通信前三次握手建立连接;结束四次挥手断开;具备确认重传、拥塞控制、滑动窗口。

2. IP地址相关

IP地址 = 网络位 + 主机位

  • 网络位:标识属于哪一个局域网
  • 主机位:局域网内主机编号
  • 网段地址:主机位全部为0
  • 广播地址:主机位全部为1,向局域网所有主机发送数据

IP地址分类

类别 地址范围 默认子网掩码 用途 私有网段
A类 1.0.0.0‑126.255.255.255 255.0.0.0 超大型网络 10.0.0.0/8
B类 128.0.0.0‑191.255.255.255 255.255.0.0 大中型网络 172.16‑31段
C类 192.0.0.0‑223.255.255.255 255.255.255.0 中小型局域网 192.168.x.x
D类 224‑239 --- 组播 ---
E类 240‑255 --- 实验保留 ---

子网掩码 :用来区分IP地址中的网络位与主机位;二进制1代表网络位,0代表主机位。

示例:192.168.0.175/24等价子网掩码255.255.255.0

MAC地址

网卡出厂自带唯一硬件地址,局域网内部依靠MAC地址完成帧通信;跨网段依靠IP地址路由。

3. 虚拟机两种网络模式

  1. NAT模式

    • Windows主机上网,虚拟机就可以上网;虚拟机使用虚拟IP。
    • 虚拟机可以访问外网,外部局域网设备无法主动访问虚拟机
    • 适合开发调试上网,不适合做服务器。
  2. 桥接模式

    • 虚拟机和物理主机处于同一个局域网,分配独立真实局域网IP。
    • 虚拟机既可以访问外网,局域网其他设备也可以访问虚拟机,可以作为服务器。
    • 会占用局域网一个IP地址。

修改网卡配置文件/etc/network/interfaces设置dhcp自动获取IP;ping www.baidu.com测试网络连通。

4. 网络字节序

网络通信统一使用大端字节序 :低地址存放高位数据。

本地PC一般为小端模式:低地址存放低位数据。

字节序转换函数:

c 复制代码
//主机短整型 → 网络大端
uint16_t htons(uint16_t hostshort);
//主机长整型 → 网络大端
uint32_t htonl(uint32_t hostlong);

//网络大端 → 主机短整型
uint16_t ntohs(uint16_t netshort);
//网络大端 → 主机长整型
uint32_t ntohl(uint32_t netlong);

IP地址字符串与网络二进制转换:

c 复制代码
in_addr_t inet_addr(const char *cp);  //点分字符串ip转网络大端整数
char *inet_ntoa(struct in_addr in);   //网络二进制ip转回点分字符串

IPv4套接字地址结构体sockaddr_in

c 复制代码
struct sockaddr_in {
    sa_family_t    sin_family; /* 协议族 AF_INET */
    in_port_t      sin_port;   /* 端口号(网络字节序) */
    struct in_addr sin_addr;   /* ip地址(网络字节序) */
};

5. UDP编程(用户数据报)

UDP特点:无连接,发送不需要建立连接;每个数据包独立;不可靠;适合视频、广播。

核心API

c 复制代码
//1. 创建套接字
int socket(int domain, int type, int protocol);
// domain: AF_INET ipv4
// type: SOCK_DGRAM UDP数据报
// protocol: 填0默认协议

//2. 发送数据
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

//3. 接收数据
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

//4. 绑定IP端口到套接字
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • bind():将本机IP+端口绑定到socket;服务器一般需要bind;客户端一般不需要bind,操作系统自动分配临时端口。
  • 端口号:1‑1023系统保留端口;自定义程序建议使用1024‑65535。

UDP客户端流程:socket → sendto / recvfrom → close

UDP服务器流程:socket → bind → recvfrom / sendto → close

6. TCP编程(流式套接字 SOCK_STREAM)

TCP特点:面向连接;三次握手建立连接;四次挥手断开连接;可靠传输;字节流。

核心API

c 复制代码
//创建tcp套接字
int socket(int domain, int type, int protocol);
//type: SOCK_STREAM

//客户端:向服务器发起连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

//服务器:开启监听
int listen(int sockfd, int sockfd, int backlog);
//backlog:未处理连接请求队列最大长度

//服务器:接受客户端连接,返回新通信fd
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

//TCP发送数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

//TCP接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

recv返回值说明:

  • 0:成功收到字节数

  • 0:对端已经关闭连接
  • -1:出错

TCP客户端流程 :socket → connect → send / recv → close

TCP服务器流程:socket → bind → listen → accept → send/recv → close

注意:accept返回新的文件描述符专门和客户端通信;listen的fd只用来监听连接,不收发业务数据。

✨学习重点

  1. 分清OSI七层模型与实际使用的TCP/IP四层模型;分清TCP与UDP的特性差异。
  2. IP地址、子网掩码作用;A/B/C/D/E五类IP划分;私有IP概念。
  3. NAT模式与桥接模式虚拟机网络区别:NAT不能被外部访问,桥接可以做服务器。
  4. 网络通信一律使用大端字节序 ;必须掌握htons / ntohs端口字节序转换,忘记转换通信完全异常。
  5. UDP:无连接,使用sendto/recvfrom收发,服务器必须bind绑定端口。
  6. TCP:面向连接,三次握手建立连接;listen开启监听;accept返回新通信fd;recv返回0代表对方关闭socket。
  7. sockaddr_in结构体:sin_port端口必须网络字节序,sin_addr.s_addrIP网络字节序。
  8. bind作用:绑定本机IP+端口到套接字;服务器一般bind;客户端操作系统自动分配临时端口,可不bind。

⚠️易错点&踩坑记录

  1. 端口忘记htons字节序转换,直接填数字,端口错乱,无法通信,高频错误。
  2. IP地址直接赋值点分字符串,没有使用inet_addr转为网络二进制,程序运行异常。
  3. TCP中混淆监听socket fd 和 accept返回的通信fd;用listen的fd调用send/recv,直接出错。
  4. recv返回值判断错误:没有判断返回0,对方关闭连接后程序还继续recv,逻辑异常。
  5. bind绑定别人机器的IP地址,bind失败;bind只能绑定本机网卡拥有的IP。
  6. 同一个端口没有释放,程序重复启动bind报地址已被占用。
  7. UDP不要使用send/recv,UDP必须使用sendto、recvfrom,需要传入对端地址结构体。
  8. 虚拟机NAT模式下,外部主机无法访问虚拟机的服务器程序,需要切换桥接模式。
  9. listen的backlog不是最大客户端连接数,是未完成连接队列的长度。
  10. sockaddr_in强转问题:API参数需要struct sockaddr*,定义sockaddr_in之后强制类型转换传入,类型不匹配编译告警。
  11. 不要使用1‑1023端口,属于系统知名端口,容易权限不足bind失败。

📝今日学习小结

今天学习Linux网络编程基础4.4章节,掌握网络协议分层模型、IP地址分类、子网掩码,理解NAT与桥接两种虚拟机网络模式。

  1. 网络传输统一使用大端字节序 ,主机小端需要调用htons完成转换,是网络编程最容易踩坑点。
  2. UDP无连接,使用sendto/recvfrom;服务器必须bind绑定端口,客户端可以不用bind。
  3. TCP面向连接,三次握手建立连接;服务器流程socket‑bind‑listen‑acceptaccept返回新fd专门与客户端通信;recv返回0代表对端关闭连接。
相关推荐
Uncertainty!!1 小时前
Linux 主机无法完成校园网认证排查记录:从 DHCP、ARP 到 Portal 认证流程分析
linux·运维·服务器
神威难绷泪1 小时前
Linux消息队列 & 共享内存 笔记
linux·消息队列·共享内存
mounter6251 小时前
突破零停机演进:Linux 内核 Live Update Orchestrator (LUO) 架构设计与热升级演进
linux·服务器·linux kernel·kernel·kho·luo
波多利希最高礼仪的握力器2 小时前
安全复制SCP
linux·服务器·安全
国科安芯2 小时前
星载CAN总线通信网络中抗辐射MCU的通信可靠性设计分析
网络·人工智能·分布式·单片机·嵌入式硬件·架构
xiaoye-duck2 小时前
《Linux网络编程·加餐》进程间关系与守护进程
linux·网络
GeW2 小时前
RHCE高频考题精讲,精准突击快速拿证
linux
MyFreeIT2 小时前
Let‘s Encrypt SSL 製作免費證書
网络协议·https·ssl
weixin_430750932 小时前
开源ids网络入侵检测系统Security Onion部署
网络·security onion·开源ids入侵检测系统