C++网络编程知识汇总
C++网络编程是利用C++语言实现计算机网络通信的核心技术,涉及TCP/IP协议栈、套接字编程、多线程处理、I/O复用等核心领域。以下从协议栈基础、Socket编程、高级网络编程技术、实际应用案例四个维度展开系统化总结。
一、协议栈基础架构
1.1 OSI七层模型与TCP/IP四层模型
• OSI七层模型
物理层(Ethernet/RS-232)、数据链路层(Ethernet MAC/PPP)、网络层(IP/ICMP/ARP)、传输层(TCP/UDP)、会话层(NetBIOS/RPC)、表示层(SSL/TLS/JPEG)、应用层(HTTP/FTP/SMTP)。
• TCP/IP四层模型
网络接口层(Ethernet/Wi-Fi)、网络层(IP/ICMP/ARP)、传输层(TCP/UDP)、应用层(HTTP/FTP/DNS/SMTP)。TCP/IP将OSI的会话层、表示层、应用层合并为应用层,是互联网通信的实际标准。
1.2 核心协议解析
• HTTP协议
基于请求-响应模型,支持GET/POST/PUT/DELETE方法,默认端口80(HTTP)和443(HTTPS)。HTTP/1.1引入持久连接,HTTP/2实现多路复用,HTTP/3基于QUIC协议(UDP实现)。
• TCP协议
面向连接、可靠传输协议,通过三次握手建立连接(SYN→SYN-ACK→ACK),四次挥手释放连接(FIN→ACK→FIN→ACK)。采用滑动窗口控制流量,慢启动/拥塞避免算法避免网络拥塞。
• UDP协议
无连接、不可靠传输协议,适用于实时性要求高的场景(如视频会议、在线游戏)。头部开销仅8字节,传输效率高于TCP。
• IP协议
网络层协议,负责数据包路由。IPv4使用32位地址(如192.168.1.1),IPv6使用128位地址(如2001:0db8::ff00:0042)。支持分片与重组,最大传输单元(MTU)通常为1500字节。
二、Socket编程基础
2.1 Socket类型与工作流程
• 流式套接字(SOCK_STREAM)
基于TCP协议,提供可靠、面向连接的字节流传输。适用于文件传输、网页浏览等场景。工作流程:创建套接字→绑定IP和端口→监听连接→接受客户端连接→数据收发→关闭连接。
• 数据报套接字(SOCK_DGRAM)
基于UDP协议,提供无连接、不可靠的数据报传输。适用于实时性要求高但可靠性要求低的场景(如视频会议、在线游戏)。工作流程:创建套接字→绑定IP和端口(可选)→直接发送/接收数据→关闭套接字。
2.2 关键函数与数据结构
• Socket地址结构
sockaddr为通用地址结构,sockaddr_in为IPv4专用结构:
struct sockaddr_in {
short int sin_family; // 地址族(AF_INET)
unsigned short sin_port; // 端口号(需htonl转换)
struct in_addr sin_addr; // IP地址
unsigned char sin_zero[8]; // 填充字段
};
• 核心函数
• socket():创建套接字。
• bind():绑定IP和端口。
• listen():监听连接请求。
• accept():接受客户端连接。
• connect():客户端连接服务器。
• send()/recv():TCP数据收发。
• sendto()/recvfrom():UDP数据收发。
• close():关闭套接字。
2.3 TCP服务器与客户端示例
• TCP服务器代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8888
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char *hello = "Hello from server";
// 创建套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置套接字选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定套接字
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听连接请求
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 接受客户端连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
// 读取客户端数据并回复
int valread = read(new_socket, buffer, 1024);
std::cout << buffer << std::endl;
send(new_socket, hello, strlen(hello), 0);
std::cout << "Hello message sent" << std::endl;
// 关闭套接字
close(new_socket);
close(server_fd);
return 0;
}
• TCP客户端代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8888
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
// 创建套接字
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cout << "\n Socket creation error \n";
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// 转换IP地址
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
std::cout << "\nInvalid address/ Address not supported \n";
return -1;
}
// 连接服务器
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
std::cout << "\nConnection Failed \n";
return -1;
}
// 发送数据并接收响应
send(sock, hello, strlen(hello), 0);
std::cout << "Hello message sent" << std::endl;
int valread = read(sock, buffer, 1024);
std::cout << buffer << std::endl;
// 关闭套接字
close(sock);
return 0;
}
三、高级网络编程技术
3.1 多线程与I/O复用
• 多线程服务器
使用std::thread为每个客户端连接创建独立线程,提升并发处理能力。示例代码:
#include <thread>
void handle_client(int client_socket) {
char buffer[1024] = {0};
read(client_socket, buffer, 1024);
std::cout << "Message from client: " << buffer <<