【C++上岸】C++常见面试题目--网络篇(第二十六期)

大家好!😊 欢迎来到C++面试系列的第二十六期------网络篇!网络知识是面试中的高频考点,尤其对C++后端开发岗位至关重要。今天,我将继续详细拆解10个常见问题,助你轻松上岸!💡 记得收藏哦,面试前翻一翻,信心满满!🚀

一、Socket网络编程步骤

  1. TCP协议流程
    • 服务端:创建socket → 绑定bind → 监听listen → 接受accept → 读写recv/send → 关闭close
    • 客户端:创建socket → 连接connect → 读写recv/send → 关闭close
  2. UDP协议流程
    • 服务端:创建socket → 绑定bind → 接收recvfrom
    • 客户端:创建socket → 发送sendto

二、核心接口详解

函数 作用
socket() 创建套接字
bind() 绑定IP和端口
listen() 设置监听队列
accept() 接受客户端连接
connect() 发起连接请求
recv()/send() TCP数据收发
recvfrom()/sendto() UDP数据收发
setsockopt() 设置套接字选项

三、Socket在网络层级中的位置

socket 的精准定位:应用层 ↔ 传输层的"接口层"

socket 的核心作用是屏蔽传输层 / 网络层的底层细节,让应用层程序无需直接操作 TCP/UDP/IP 协议,只需调用 socket API 就能实现网络通信。具体定位拆解:

不属于传输层,但封装了传输层核心能力

传输层的核心是 TCP/UDP 协议,而 socket 是 "操作 TCP/UDP 的工具":

你在 socket 编程中指定SOCK_STREAM(对应 TCP)、SOCK_DGRAM(对应 UDP),本质是通过 socket 选择传输层协议;

TCP 的三次握手、四次挥手、数据重传,UDP 的数据报发送,都是操作系统通过 socket 接口帮应用层完成的,应用层无需关心传输层的底层逻辑。

不属于应用层,但为应用层提供唯一入口

应用层的程序(如你写的 C++ 服务端 / 客户端、浏览器、聊天软件)本身是应用层逻辑,但所有网络通信必须通过 socket 接口发起 ------ 没有 socket,应用层程序无法直接和传输层交互。

间接用到网络层 / 数据链路层,但仅为封装调用

socket 编程中你会指定 IP 地址(网络层)、端口(传输层),但这些参数是通过 socket 传递给底层协议栈的,socket 本身不处理 IP 路由、MAC 地址解析(ARP)等网络层 / 数据链路层工作,仅作为 "参数传递通道"。

Socket属于** 传输层(Transport Layer)**的编程接口,是对TCP/UDP协议的封装抽象


四、Socket常用类(C++)

cpp 复制代码
// Linux系统常用
#include <sys/socket.h> 
#include <netinet/in.h>

// Windows系统常用
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

💡 注意:C++标准库未提供原生Socket类,通常需调用操作系统API或使用第三方库(如boost::asio)


五、高并发场景优化方案

  1. 线程池技术

    cpp 复制代码
    // 伪代码示例
    ThreadPool pool(4); // 4个工作线程
    while(true) {
        SOCKET client = accept(server);
        pool.enqueue([client]{ handle_request(client); });
    }
  2. IO多路复用(select/poll/epoll)

  3. 非阻塞IO+事件驱动

  4. 连接复用(Keep-Alive)


六、洪泛攻击(Flood Attack)

通过伪造大量虚假IP的SYN请求 耗尽服务器资源:
攻击流量∝1服务器响应时间 \text{攻击流量} \propto \frac{1}{\text{服务器响应时间}} 攻击流量∝服务器响应时间1

防御方案:

✅ SYN Cookie机制 ✅ 流量清洗 ✅ 连接数限制


七、Nagle算法

作用 :合并小数据包减少网络拥堵
触发条件
{待发送数据<MSS前一包未确认 \begin{cases} \text{待发送数据} < \text{MSS} \\ \text{前一包未确认} \end{cases} {待发送数据<MSS前一包未确认

禁用方法:setsockopt(sock, TCP_NODELAY, 1)


八、select/poll/epoll对比

机制 时间复杂度 最大连接数 触发方式
select O(n)O(n)O(n) FD_SETSIZE 轮询
poll O(n)O(n)O(n) 无限制 轮询
epoll O(1)O(1)O(1) 系统上限 回调

🔥 epoll的优势:

  • 无需遍历所有fd
  • 支持边缘触发(ET)和水平触发(LT)
  • 内核事件通知机制

九、性能优化技巧

  1. 零拷贝技术sendfile()

  2. 内存池管理:避免频繁malloc

  3. 缓冲区设计 :环形缓冲区减少拷贝

    cpp 复制代码
    class RingBuffer {
        char* buffer;
        int read_pos, write_pos;
    };
  4. SO_REUSEPORT选项:端口复用

  5. 避免内存拷贝writev()/readv()


十、TCP服务端创建示例

cpp 复制代码
#include <iostream>
#include <sys/socket.h>

int main() {
    // 1. 创建socket
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    // 2. 绑定地址
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(8080);
    bind(server_fd, (sockaddr*)&addr, sizeof(addr));
    
    // 3. 监听连接
    listen(server_fd, 5);
    
    // 4. 接受请求
    sockaddr_in client_addr{};
    socklen_t len = sizeof(client_addr);
    int client_fd = accept(server_fd, (sockaddr*)&client_addr, &len);
    
    // 5. 数据处理...
}

十一、TCP客户端创建示例

cpp 复制代码
#include <sys/socket.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(8080);
    
    connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    
    // 发送数据...
    send(sock, "Hello Server!", 13, 0);
}

💪 掌握这些核心知识点,网络面试不再慌! 觉得有用的话点个赞吧~ ✨
// 祝你面试顺利,offer拿到手软!🚀

相关推荐
老四啊laosi2 小时前
[C++初阶] 10. string模拟实现
c++·stl·string
七夜zippoe2 小时前
WebSocket实时通信系统构建:从握手协议到生产级实战
网络·python·websocket·网络协议·心跳
玉树临风江流儿2 小时前
linux使用 nmcli工具扫描、连接WiFi
网络
EmbedLinX2 小时前
C++ STL 学习笔记
c++·stl
m0_736919102 小时前
C++中的策略模式实战
开发语言·c++·算法
孞㐑¥2 小时前
算法—位运算
c++·经验分享·笔记·算法
从此不归路2 小时前
Qt5 进阶【9】模型-视图框架实战:从 TableView 到自定义模型的一整套落地方案
开发语言·c++·qt
乐维_lwops2 小时前
利用Zabbix监控指定IP列表的ping
网络·tcp/ip·zabbix
honsor2 小时前
机房/档案室专用以太网温湿度传感器:智能监控赋能环境安全
运维·网络·物联网·安全