欢迎光临
我们一直在努力

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

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

一、Socket网络编程步骤

  • TCP协议流程
    • 服务端:创建socket → 绑定bind → 监听listen → 接受accept → 读写recv/send → 关闭close
    • 客户端:创建socket → 连接connect → 读写recv/send → 关闭close
  • 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++)

    // Linux系统常用
    #include <sys/socket.h>
    #include <netinet/in.h>

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

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


    五、高并发场景优化方案

  • 线程池技术// 伪代码示例
    ThreadPool pool(4); // 4个工作线程
    while(true) {
    SOCKET client = accept(server);
    pool.enqueue([client]{ handle_request(client); });
    }

  • IO多路复用(select/poll/epoll)
  • 非阻塞IO+事件驱动
  • 连接复用(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)
    • 内核事件通知机制

    九、性能优化技巧

  • 零拷贝技术:sendfile()
  • 内存池管理:避免频繁malloc
  • 缓冲区设计:环形缓冲区减少拷贝class RingBuffer {
    char* buffer;
    int read_pos, write_pos;
    };

  • SO_REUSEPORT选项:端口复用
  • 避免内存拷贝:writev()/readv()

  • 十、TCP服务端创建示例

    #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客户端创建示例

    #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拿到手软!🚀

    赞(0)
    未经允许不得转载:171主机测评 » 【C++上岸】C++常见面试题目--网络篇(第二十六期)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址