学懂C++(三十八):深入详解C++网络编程:套接字(Socket)开发技术

目录

一、概述与基础概念

[1.1 套接字(Socket)概念](#1.1 套接字(Socket)概念)

[1.2 底层原理与网络协议](#1.2 底层原理与网络协议)

[1.2.1 网络协议](#1.2.1 网络协议)

[1.2.2 套接字工作原理](#1.2.2 套接字工作原理)

二、C++套接字编程核心技术

[2.1 套接字编程的基本步骤](#2.1 套接字编程的基本步骤)

[2.2 套接字编程详细实现](#2.2 套接字编程详细实现)

[2.2.1 创建套接字](#2.2.1 创建套接字)

[2.2.2 绑定地址](#2.2.2 绑定地址)

[2.2.3 监听和接受连接(服务端)](#2.2.3 监听和接受连接(服务端))

[2.2.4 客户端连接](#2.2.4 客户端连接)

[2.2.5 发送和接收数据](#2.2.5 发送和接收数据)

[2.2.6 关闭套接字](#2.2.6 关闭套接字)

[2.3 经典实例:TCP客户端和服务器](#2.3 经典实例:TCP客户端和服务器)

[2.3.1 TCP服务器](#2.3.1 TCP服务器)

[2.3.2 TCP客户端](#2.3.2 TCP客户端)

运行结果

三、深入理解与高级应用

[3.1 异步I/O与事件驱动编程](#3.1 异步I/O与事件驱动编程)

[3.2 高效并发编程](#3.2 高效并发编程)

[3.3 使用Boost.Asio进行异步编程](#3.3 使用Boost.Asio进行异步编程)

完整代码示例:使用Boost.Asio进行异步TCP服务器

BoostServer.cpp

四、核心技术及高级话题

[4.1 同步I/O与异步I/O的选择](#4.1 同步I/O与异步I/O的选择)

[4.2 多线程与事件驱动模型](#4.2 多线程与事件驱动模型)

[4.3 高效网络编程的关键技术](#4.3 高效网络编程的关键技术)

[4.4 使用C++11/14/17/20新特性优化网络编程](#4.4 使用C++11/14/17/20新特性优化网络编程)

五、实例:高效异步HTTP服务器

[5.1 异步HTTP服务器](#5.1 异步HTTP服务器)

运行结果

六、拓展思考

1、套接字(Socket)是什么?它包括哪些核心内容?

套接字的定义

套接字的核心内容

[1. 套接字类型](#1. 套接字类型)

[2. 地址族](#2. 地址族)

[3. 套接字的基本操作](#3. 套接字的基本操作)

套接字的高级内容

[2、套接字 socket是基于哪个网络协议的?是TCP还是Http?](#2、套接字 socket是基于哪个网络协议的?是TCP还是Http?)

总结


网络编程是现代软件开发的重要领域,广泛应用于客户端-服务器应用、分布式系统和互联网应用开发中。C++作为一门强大且高效的编程语言,在进行低层次、高性能网络编程时有显著优势。本文将深入剖析C++网络编程中的套接字(Socket)开发技术,详细讲解其概念、底层原理、网络协议知识、本质及需要掌握的核心点、实现方式等,同时结合经典实例进行解析。

一、概述与基础概念

1.1 套接字(Socket)概念

概念:套接字(Socket)是网络编程中用于描述网络连接的端点,是操作系统提供的用于网络通信的基础抽象。它可以看作是网络中的"文件",通过对套接字的操作实现数据的发送和接收。

核心点

  • 类型:主要包括流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM),分别对应TCP和UDP协议。
  • 地址:由IP地址和端口号组成,用于标识网络中的设备和应用。

1.2 底层原理与网络协议

1.2.1 网络协议

IP地址:标识网络中的主机,分为IPv4(如192.168.1.1)和IPv6(如2001:db8::1)地址。

端口号:标识主机上的应用程序,范围为0到65535。常见的端口号如HTTP的80端口、HTTPS的443端口等。

TCP/IP协议族:互联网的基础协议族,包含传输层的TCP和UDP、网络层的IP等。

  • TCP(传输控制协议):提供可靠的字节流服务,包括连接建立、数据传输、连接终止等过程。TCP通过三次握手建立连接,四次挥手终止连接。
  • UDP(用户数据报协议):提供不可靠的消息传递服务,数据报可能无序到达或丢失。UDP适用于实时性要求较高的应用,如视频传输、在线游戏等。
1.2.2 套接字工作原理

套接字是一种抽象层,使得应用程序能够通过操作系统提供的API进行网络通信。它包含以下基本操作:

  • 创建:通过系统调用创建套接字。
  • 绑定:将套接字绑定到特定的IP地址和端口。
  • 监听:在服务端,套接字监听来自客户端的连接请求。
  • 连接:在客户端,套接字连接到服务端的指定地址和端口。
  • 发送/接收:通过套接字发送和接收数据。
  • 关闭:关闭套接字,释放系统资源。

二、C++套接字编程核心技术

2.1 套接字编程的基本步骤

  1. 创建套接字
  2. 绑定地址
  3. 监听(服务端)
  4. 接受连接(服务端)
  5. 连接(客户端)
  6. 发送和接收数据
  7. 关闭套接字

2.2 套接字编程详细实现

2.2.1 创建套接字
cpp 复制代码
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
    perror("socket creation failed");
    exit(EXIT_FAILURE);
}

解析

  • socket(AF_INET, SOCK_STREAM, 0) :创建一个TCP套接字。AF_INET表示使用IPv4,SOCK_STREAM表示使用TCP协议。
  • 返回值:成功时返回套接字文件描述符,失败时返回-1。
2.2.2 绑定地址
cpp 复制代码
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);

if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
    perror("bind failed");
    close(sockfd);
    exit(EXIT_FAILURE);
}

解析

  • struct sockaddr_in :定义IP地址和端口,sin_family设为AF_INETsin_addr.s_addr设为INADDR_ANY表示接受任何IP地址,sin_port设为端口(通过htons函数转换为网络字节序)。
  • bind:将地址绑定到套接字。
2.2.3 监听和接受连接(服务端)
cpp 复制代码
if (listen(sockfd, 5) < 0) {
    perror("listen failed");
    close(sockfd);
    exit(EXIT_FAILURE);
}

struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int newsockfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
if (newsockfd < 0) {
    perror("accept failed");
    close(sockfd);
    exit(EXIT_FAILURE);
}

解析

  • listen:将套接字置于监听模式,准备接受连接。第二个参数为连接队列的最大长度。
  • accept :接受客户端连接,返回新的套接字用于通信。client_addr保存客户端地址信息。
2.2.4 客户端连接
cpp 复制代码
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {
    perror("invalid address");
    exit(EXIT_FAILURE);
}

if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
    perror("connect failed");
    close(sockfd);
    exit(EXIT_FAILURE);
}

解析

  • inet_pton :将字符串形式的IP地址转换为struct in_addr
  • connect:将套接字连接到指定的服务器地址和端口。
2.2.5 发送和接收数据
cpp 复制代码
const char* message = "Hello, Server!";
send(sockfd, message, strlen(message), 0);

char buffer[1024];
int n = recv(sockfd, buffer, sizeof(buffer), 0);
buffer[n] = '\0';
printf("Received: %s\n", buffer);

解析

  • send:发送数据,第四个参数为标志位,通常为0。
  • recv:接收数据,返回接收的字节数。
2.2.6 关闭套接字
cpp 复制代码
close(sockfd);

2.3 经典实例:TCP客户端和服务器

2.3.1 TCP服务器
cpp 复制代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT 8080

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");
        close(server_fd);
        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");
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    // 接受客户端连接
    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept");
        close(server_fd);
        exit(EXIT_FAILURE);
    }
    
    // 读取客户端数据
    int valread = read(new_socket, buffer, 1024);
    printf("%s\n", buffer);
    
    // 发送数据到客户端
    send(new_socket, hello, strlen(hello), 0);
    printf("Hello message sent\n");
    
    // 关闭套接字
    close(new_socket);
    close(server_fd);
    return 0;
}

解析

  • 创建套接字socket(AF_INET, SOCK_STREAM, 0)
  • 绑定地址bind
  • 监听连接listen
  • 接受连接accept
  • 读取数据read
  • 发送数据send
  • 关闭套接字close
2.3.2 TCP客户端
cpp 复制代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 8080

int main() {
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    const char* hello = "Hello from client";
    char buffer[1024] = {0};

    // 创建套接字
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation error");
        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) {
        perror("Invalid address/ Address not supported");
        return -1;
    }
    
    // 连接服务器
    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection Failed");
        return -1;
    }
    
    // 发送数据到服务器
    send(sock, hello, strlen(hello), 0);
    printf("Hello message sent\n");
    
    // 读取服务器响应
    valread = read(sock, buffer, 1024);
    printf("%s\n", buffer);
    
    // 关闭套接字
    close(sock);
    return 0;
}

解析

  • 创建套接字socket(AF_INET, SOCK_STREAM, 0)
  • 连接服务器connect
  • 发送数据send
  • 读取数据read
  • 关闭套接字close

运行结果

  1. 启动服务器:

    bash 复制代码
    ./server

    输出

    cpp 复制代码
    Hello from client
    Hello message sent
  2. 启动客户端:

    bash 复制代码
    ./client

    输出

    cpp 复制代码
    Hello message sent
    Hello from server

三、深入理解与高级应用

3.1 异步I/O与事件驱动编程

异步I/O:允许程序在等待I/O操作完成时继续执行其他任务,提高程序的并发性能。实现方式包括:

  • 多线程:每个I/O操作分配一个线程处理。
  • 事件驱动 :使用事件循环处理I/O事件,例如selectpollepoll等。
3.2 高效并发编程

多线程网络编程

  • 线程同步:避免多个线程同时访问共享资源,使用互斥锁、条件变量等。
  • 线程池:复用线程,减少线程创建和销毁的开销,提高性能。

实例:使用线程池处理多个客户端连接。

cpp 复制代码
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT 8080

std::mutex mtx;  // 互斥锁用于保护共享资源
std::condition_variable cv;  // 条件变量用于线程间同步
std::queue<int> clients;  // 用于存储待处理的客户端套接字

// 处理客户端连接的函数
void handle_client(int client_sock) {
    char buffer[1024];
    int n = recv(client_sock, buffer, sizeof(buffer), 0);  // 接收客户端消息
    if (n > 0) {
        buffer[n] = '\0';  // 添加字符串终止符
        std::cout << "Received: " << buffer << std::endl;
        const char* response = "Message received";
        send(client_sock, response, strlen(response), 0);  // 发送响应给客户端
    }
    close(client_sock);  // 关闭客户端连接
}

// 工作线程函数,用于处理客户端连接
void worker() {
    while (true) {
        int client_sock;
        {
            std::unique_lock<std::mutex> lock(mtx);  // 获取锁
            cv.wait(lock, [] { return !clients.empty(); });  // 等待条件变量通知
            client_sock = clients.front();  // 从队列中取出客户端套接字
            clients.pop();  // 移除队列中的套接字
        }
        handle_client(client_sock);  // 处理客户端连接
    }
}

int main() {
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);  // 创建TCP套接字
    if (server_sock < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;  // 使用IPv4
    server_addr.sin_addr.s_addr = INADDR_ANY;  // 绑定所有可用的网络接口
    server_addr.sin_port = htons(PORT);  // 绑定端口

    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind failed");
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    if (listen(server_sock, 5) < 0) {  // 设置监听队列的最大长度为5
        perror("listen failed");
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    // 创建多个工作线程
    std::vector<std::thread> workers;
    for (int i = 0; i < 4; ++i) {
        workers.emplace_back(worker);  // 启动工作线程
    }

    while (true) {
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        int client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len);  // 接受客户端连接
        if (client_sock < 0) {
            perror("accept failed");
            continue;
        }
        {
            std::lock_guard<std::mutex> lock(mtx);  // 获取锁
            clients.push(client_sock);  // 将客户端套接字添加到队列中
        }
        cv.notify_one();  // 通知一个工作线程
    }

    for (auto& t : workers) {
        t.join();  // 等待所有工作线程结束
    }

    close(server_sock);  // 关闭服务器套接字
    return 0;
}
3.3 使用Boost.Asio进行异步编程

Boost.Asio 是一个强大且灵活的库,提供了跨平台的异步I/O操作,支持多平台。我们继续讨论如何使用Boost.Asio实现一个高效的异步TCP服务器。

完整代码示例:使用Boost.Asio进行异步TCP服务器

BoostServer.cpp
cpp 复制代码
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <utility>

using boost::asio::ip::tcp;

// 会话类,用于管理单个客户端连接
class Session : public std::enable_shared_from_this<Session> {
public:
    explicit Session(tcp::socket socket)
        : socket_(std::move(socket)) {}

    // 开始会话
    void start() {
        do_read();  // 开始读取数据
    }

private:
    // 异步读取数据
    void do_read() {
        auto self(shared_from_this());
        socket_.async_read_some(boost::asio::buffer(data_, max_length),
            [this, self](boost::system::error_code ec, std::size_t length) {
                if (!ec) {
                    std::cout << "Received: " << data_ << std::endl;
                    do_write(length);  // 读取完成后写入数据
                }
            });
    }

    // 异步写入数据
    void do_write(std::size_t length) {
        auto self(shared_from_this());
        boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    do_read();  // 写入完成后继续读取数据
                }
            });
    }

    tcp::socket socket_;  // 套接字
    enum { max_length = 1024 };
    char data_[max_length];  // 数据缓冲区
};

// 服务器类,用于管理客户端连接
class Server {
public:
    Server(boost::asio::io_context& io_context, short port)
        : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
        do_accept();  // 开始接受连接
    }

private:
    // 异步接受连接
    void do_accept() {
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    std::make_shared<Session>(std::move(socket))->start();
                }
                do_accept();  // 继续接受下一次连接
            });
    }

    tcp::acceptor acceptor_;  // 接受器,用于监听连接
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: BoostServer <port>\n";
            return 1;
        }

        boost::asio::io_context io_context;  // IO上下文
        Server s(io_context, std::atoi(argv[1]));  // 创建服务器
        io_context.run();  // 运行IO上下文
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

解析

  1. Session类 :管理单个客户端连接。
    • do_read :异步读取数据,使用async_read_some方法。
    • do_write :异步写入数据,使用async_write方法。
  2. Server类 :管理所有客户端连接。
    • do_accept :异步接受新的连接,使用async_accept方法。
  3. main函数 :创建io_contextServer实例,调用io_context.run()运行事件循环。

四、核心技术及高级话题

4.1 同步I/O与异步I/O的选择

同步I/O

  • 简单直接,易于编程和调试。
  • 适合处理少量并发连接。

异步I/O

  • 提高并发性能,适合高并发场景。
  • 编程复杂度较高,需要处理回调、状态管理等。
4.2 多线程与事件驱动模型

多线程模型

  • 每个连接分配一个线程处理。
  • 线程同步开销大,线程数量有限制。

事件驱动模型

  • 使用事件循环处理I/O事件。
  • 无需大量线程,仅需少量线程处理所有连接。
4.3 高效网络编程的关键技术
  • I/O复用 :如selectpollepoll,实现单线程高效处理多个连接。
  • 零拷贝:减少内存拷贝,提高数据传输效率。
  • 内存池:复用内存,减少内存分配和释放开销。
  • 负载均衡:分配连接到不同服务器,均衡负载,提高系统吞吐量。
4.4 使用C++11/14/17/20新特性优化网络编程
  • 智能指针 :如std::shared_ptrstd::unique_ptr,管理动态内存,避免内存泄漏。
  • lambda表达式:简化回调函数编写。
  • std::thread:标准多线程库,简化线程创建和管理。
  • std::async:异步任务执行,简化异步编程。

五、实例:高效异步HTTP服务器

5.1 异步HTTP服务器

使用Boost.Asio实现一个高效的异步HTTP服务器:

cpp 复制代码
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <utility>

using boost::asio::ip::tcp;

class HttpSession : public std::enable_shared_from_this<HttpSession> {
public:
    explicit HttpSession(tcp::socket socket)
        : socket_(std::move(socket)) {}

    void start() {
        do_read();
    }

private:
    void do_read() {
        auto self(shared_from_this());
        socket_.async_read_some(boost::asio::buffer(buffer_),
            [this, self](boost::system::error_code ec, std::size_t length) {
                if (!ec) {
                    handle_request(length);
                }
            });
    }

    void handle_request(std::size_t length) {
        std::string data(buffer_.data(), length);
        std::cout << "Request: " << data << std::endl;

        std::string response = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, world!";
        auto self(shared_from_this());
        boost::asio::async_write(socket_, boost::asio::buffer(response),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    socket_.shutdown(tcp::socket::shutdown_both, ec);
                }
            });
    }

    tcp::socket socket_;
    std::array<char, 8192> buffer_;
};

class HttpServer {
public:
    HttpServer(boost::asio::io_context& io_context, short port)
        : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
        do_accept();
    }

private:
    void do_accept() {
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    std::make_shared<HttpSession>(std::move(socket))->start();
                }
                do_accept();
            });
    }

    tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: HttpServer <port>\n";
            return 1;
        }

        boost::asio::io_context io_context;
        HttpServer server(io_context, std::atoi(argv[1]));
        io_context.run();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

解析

  1. HttpSession类 :管理单个HTTP会话。
    • do_read:异步读取HTTP请求。
    • handle_request:处理HTTP请求,生成响应。
    • do_write:异步发送HTTP响应。
  2. HttpServer类 :管理所有HTTP会话。
    • do_accept:异步接受新的HTTP连接。
  3. main函数 :创建io_contextHttpServer实例,调用io_context.run()运行事件循环。

运行结果

  1. 启动HTTP服务器:

    bash 复制代码
    ./HttpServer 8080
  2. 使用浏览器或curl访问服务器:

    bash 复制代码
    curl http://localhost:8080

输出

cpp 复制代码
Hello, world!

六、拓展思考

1、套接字(Socket)是什么?它包括哪些核心内容?

套接字(Socket)是计算机网络编程中一个重要的概念,它提供了一种通信的抽象,使得程序可以通过网络进行数据传输。套接字在应用层和传输层之间起到了桥梁作用,使得不同主机上的应用程序能够进行通信。换句话说,套接字是网络通信的端点,负责处理网络协议栈中的底层细节。

套接字的定义

套接字是一个网络编程接口,允许程序发送和接收数据,通过IP地址和端口号唯一标识网络中的通信端点。套接字可以基于多种传输协议进行操作,最常见的有TCP(传输控制协议)和UDP(用户数据报协议)。

套接字的核心内容

套接字编程涉及多个核心概念和操作步骤,下面详细介绍这些内容:

1. 套接字类型
  • SOCK_STREAM:使用TCP协议,提供可靠的面向连接的通信。
  • SOCK_DGRAM:使用UDP协议,提供不可靠的无连接的通信。
  • SOCK_RAW:使用原始套接字,允许直接访问底层协议,如IP协议,通常用于网络测试和低层次的网络编程。
2. 地址族
  • AF_INET:IPv4地址族。
  • AF_INET6:IPv6地址族。
  • AF_UNIX:本地通信的Unix套接字。
3. 套接字的基本操作
  • 创建套接字 :使用socket()系统调用创建一个套接字。
  • 绑定地址 :使用bind()将套接字绑定到本地地址和端口。
  • 监听(仅用于TCP服务器) :使用listen()将套接字置于监听模式,等待客户端连接。
  • 接受连接(仅用于TCP服务器) :使用accept()接受客户端连接,返回新的套接字用于通信。
  • 连接(仅用于TCP客户端) :使用connect()将套接字连接到服务器地址。
  • 发送数据 :使用send()sendto()发送数据。
  • 接收数据 :使用recv()recvfrom()接收数据。
  • 关闭套接字 :使用close()关闭套接字,释放资源。
套接字的高级内容
  • 非阻塞模式:套接字可以设置为非阻塞模式,使得I/O操作不会阻塞程序执行。
  • 多线程/多进程:使用多线程或多进程处理多个客户端连接,提高并发性能。
  • 异步I/O :使用异步I/O操作,如selectpollepoll或Boost.Asio,实现高效的事件驱动编程。
  • 安全套接字:使用SSL/TLS加密通信,确保数据传输的安全性。

概括总结

套接字(Socket)是网络编程中关键的抽象和接口,提供了通过网络进行数据传输的基本功能。理解和掌握套接字的核心内容和操作步骤是进行网络编程的基础。通过深入学习和实践,开发者可以灵活地使用套接字进行各种网络应用的开发,从简单的客户端-服务器通信到复杂的分布式系统。

2、套接字 socket是基于哪个网络协议的?是TCP还是Http?

套接字(Socket)是一种网络编程的抽象,提供了一种通用的接口,使得程序能够灵活地使用不同的网络协议进行通信。套接字并不局限于某一种协议,可以基于TCP(SOCK_STREAM)或UDP(SOCK_DGRAM)等多种协议进行操作。HTTP协议是一种应用层协议,通常运行在TCP套接字之上。通过掌握套接字编程,可以实现各种网络应用,从简单的客户端-服务器通信到复杂的分布式系统。

总结

本文深入探讨了C++网络编程中的套接字(Socket)开发技术,详细讲解了其概念、底层原理、网络协议知识、本质及需要掌握的核心点,并通过经典实例进行解析。我们介绍了同步与异步I/O、多线程与事件驱动模型、高效网络编程的关键技术,最后详细展示了如何使用Boost.Asio实现一个高效的异步HTTP服务器。通过这些技术和示例代码,高级C++开发者可以深入理解和掌握网络编程的关键技术,为开发高效、可扩展的网络应用打下坚实的基础。希望这些代码和注释能够帮助你更好地理解和应用C++网络编程。

相关推荐
是小崔啊5 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama10 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全13 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050614 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc19 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob23 分钟前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
羚羊角uou26 分钟前
【C++】优先级队列以及仿函数
开发语言·c++
姚先生9729 分钟前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
FeboReigns31 分钟前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns34 分钟前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++