本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文介绍了一个名为BBTCP的C++编写的TCP网络库,版本5.3。该库使用Windows平台特有的IOCP技术,实现高效的异步网络I/O操作。BBTCP的特点包括高性能、代码体积小且易于理解,非常适合初学者学习和实践。文章进一步探讨了TCP协议的基础知识,IOCP的异步I/O模型,以及C++网络编程的要点,包括异步I/O的概念和优势。BBTCP库的完整源代码提供了深入学习和理解网络编程架构和实现细节的机会。
IOCP

1. C++ TCP网络编程基础

1.1 网络编程概述

网络编程是一种使计算机能够通过网络连接进行数据交换的技术。在C++中,TCP是用于实现网络通信的一种协议,它为网络通信提供了可靠的、面向连接的服务。TCP/IP模型在C++网络编程中占据了核心地位,确保了数据能够准确无误地从源头传输到目的地。

1.2 C++中的套接字编程

套接字(Socket)是网络通信的基本构件。在C++中使用套接字进行网络编程,首先需要创建套接字,然后将其绑定到一个地址和端口上,接着监听连接请求,并接受连接来开始数据的发送和接收。示例代码如下:

// 创建套接字
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// 绑定套接字到本地地址和端口
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8080);
bind(s, (struct sockaddr *)&server, sizeof(server));
// 监听连接请求
listen(s, 3);

1.3 TCP通信流程

TCP通信流程包括三次握手建立连接、数据传输和四次挥手断开连接。在C++网络编程中,你需要了解这些机制,以便在实际编程中处理可能出现的异常和错误。理解这些概念有助于编写出健壮且高效的网络应用。

通过本章,我们将建立C++ TCP网络编程的基础,并为深入探讨更高级的主题打下坚实的基础。接下来的章节,我们将深入分析IOCP技术,这是Windows平台上实现高效网络I/O的关键技术之一。

2. IOCP技术深入解析

2.1 IOCP技术原理

2.1.1 IOCP的工作机制

IOCP(I/O Completion Ports)是Windows平台上一种高性能的异步I/O处理机制。IOCP允许线程在处理I/O操作时不必阻塞,而是继续执行其他任务,直到I/O操作完成。这种机制特别适合于网络服务器的高并发场景,因为它可以有效地利用CPU资源,提升系统的整体吞吐量。

IOCP的工作流程通常涉及以下几个步骤:

  1. 创建IOCP对象:通过调用Windows API CreateIoCompletionPort 创建一个I/O完成端口。

  2. 绑定设备到IOCP:将网络套接字或其他I/O设备与创建的IOCP关联起来。

  3. 启动异步I/O操作:通过I/O设备开始异步读写操作,此时操作会立即返回,不等待操作完成。

  4. 处理完成通知:完成端口会将已完成的I/O操作通知给系统,系统会选择一个线程来处理这些操作。每个I/O操作完成后,它都会被放入到完成端口的队列中等待线程处理。

  5. 线程处理I/O结果:一个或多个线程会不断轮询完成端口,获取并处理队列中的I/O结果。

从技术角度看,IOCP的实现依赖于Windows的内核对象。当一个异步I/O操作完成时,Windows内核会将I/O的完成信息发送到关联的完成端口,并且确保一次只有一个线程从完成端口中获取通知。这为高效并发处理提供了坚实的基础。

2.1.2 IOCP与同步I/O的对比

与传统的同步I/O相比,IOCP具有显著的优势。同步I/O在I/O操作未完成时会导致调用线程阻塞,这样既浪费了CPU时间,也降低了程序的响应性和吞吐量。

相比之下,IOCP通过将I/O操作的等待和处理分离,允许线程在I/O操作完成之前继续执行其他任务。这种方式不仅提高了CPU的利用率,还能更好地服务于其他用户请求,从而提升系统的整体性能。

举个例子,在一个文件服务器中,使用同步I/O可能会在处理大量并发文件操作时遇到瓶颈,因为每个线程在处理一个I/O操作时都不能做其他事情。而使用IOCP,服务器可以同时处理成百上千的文件读写请求,并且通过线程池有效地管理线程的分配和执行。

2.2 IOCP在Windows平台的应用

2.2.1 IOCP的系统支持和限制

IOCP在Windows平台上得到了广泛的支持,从Windows NT时代开始,这一技术就被集成在Windows的内核中。尽管如此,IOCP在应用中仍然有一些限制:

  1. 线程数量限制 :由于IOCP是通过线程池来处理I/O完成事件的,因此线程的创建和销毁都需要消耗系统资源。过多的线程可能会导致资源竞争,从而降低性能。

  2. 编程复杂度 :实现IOCP需要对Windows的内核API有较深的理解,这使得编写高效且正确的IOCP程序需要较高的技术门槛。

  3. 平台兼容性 :IOCP是一个Windows特定的技术,在其他平台上不能使用。如果需要跨平台开发,需要寻找其他类似的解决方案。

尽管有这些限制,IOCP在Windows平台上的应用依然广泛,尤其是在需要处理大量并发连接的服务器程序中,如Web服务器、数据库服务器等。

2.2.2 Windows下IOCP的编程模型

在Windows下使用IOCP的编程模型涉及以下几个核心步骤:

  1. 创建完成端口 :通过调用 CreateIoCompletionPort 创建一个完成端口。

  2. 关联I/O设备 :将输入输出设备(如套接字)与完成端口关联。

  3. 提交异步I/O请求 :将I/O请求异步提交给关联的设备。

  4. 等待I/O完成 :通过 GetQueuedCompletionStatus 函数等待I/O操作的完成。

  5. 处理完成的数据 :获取到完成的数据后,执行相应的业务逻辑处理。

下面是一个简化的代码示例,展示如何使用IOCP在Windows平台上实现异步I/O:

#include <Windows.h>
#include <iostream>

// 假设这是我们要读取的数据结构大小
const DWORD DATA_SIZE = 1024;

int main() {
    HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);

    // 绑定到IP和端口
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(8080);
    local.sin_addr.s_addr = INADDR_ANY;
    bind(serverSocket, (SOCKADDR*)&local, sizeof(local));

    // 开始监听
    listen(serverSocket, SOMAXCONN);

    // 无限循环等待连接和数据
    while (true) {
        SOCKET clientSocket;
        int clientAddrLen = sizeof(client);
        clientSocket = accept(serverSocket, (SOCKADDR*)&client, &clientAddrLen);

        // 将套接字关联到完成端口
        CreateIoCompletionPort((HANDLE)clientSocket, hCompletionPort, 0, 0);

        // 提交异步接收请求
        char buffer[DATA_SIZE];
        DWORD bytesRead = 0;
        DWORD flags = 0;
        OVERLAPPED overlapped = { 0 };

        if (WSARecv(clientSocket, (LPWSABUF)&buffer, 1, &bytesRead, &flags, &overlapped, NULL) == SOCKET_ERROR) {
            if (WSAGetLastError() != ERROR_IO_PENDING) {
                std::cerr << "WSARecv failed with error: " << WSAGetLastError() << std::endl;
            }
        }

        // 等待I/O完成
        if (GetQueuedCompletionStatus(hCompletionPort, &bytesRead, (PULONG_PTR)&clientSocket, (LPOVERLAPPED*)&overlapped, INFINITE)) {
            // 处理完成的数据
            std::cout << "Received " << bytesRead << " bytes from client." << std::endl;
        } else {
            std::cerr << "Error when processing data: " << WSAGetLastError() << std::endl;
        }
    }

    return 0;
}

在上面的代码中,我们创建了一个监听8080端口的服务器。服务器使用 accept 函数等待客户端连接,并且将每个客户端的套接字与完成端口关联起来。通过 WSARecv 函数,我们以异步方式开始接收数据。当数据接收完成后, GetQueuedCompletionStatus 函数会返回,并且我们可以在其返回的缓冲区中处理接收到的数据。

2.3 IOCP的高级话题

2.3.1 错误处理与异常管理

在IOCP编程中,错误处理和异常管理是不可忽视的部分。一个典型的异步I/O操作可能会在多个不同的时间点失败。例如,提交I/O操作时可能因为参数错误而失败,I/O操作完成时可能因为网络问题或其他原因失败。

处理这些错误的关键在于:

  1. 检查错误码 :在每次调用Windows API后,都需要检查返回的错误码。IOCP提供了多种API用于获取详细的错误信息,例如 WSAGetLastError

  2. 异常安全 :确保你的错误处理代码是异常安全的。在C++中,这通常意味着需要正确使用异常处理机制,并确保所有的资源管理都能安全地处理异常。

  3. 日志记录 :将错误信息记录到日志文件中,便于问题追踪和系统监控。

下面是一个如何处理和记录错误的示例:

// 假设这是在某个异步操作完成后的错误处理代码
DWORD errorCode = GetLastError();
if (errorCode != ERROR_SUCCESS) {
    // 打印到控制台
    std::cerr << "An error occurred: " << errorCode << std::endl;
    // 记录到日志文件
    std::ofstream logFile("error_log.txt", std::ios::app);
    logFile << "Error " << errorCode << " occurred while processing I/O operation." << std::endl;
    logFile.close();
    // 根据错误类型进行不同的错误处理逻辑
    // ...
}

2.3.2 性能优化与调试技巧

IOCP的性能优化和调试需要综合考虑多方面因素,以下是一些常见的优化方法:

  1. 使用线程池 :合理安排线程池的大小,避免创建过多或过少的线程,合理分配工作负载。

  2. 减少上下文切换 :确保高频率访问的资源被正确地同步和锁定,减少不必要的上下文切换。

  3. 缓存优化 :合理使用本地缓存,减少对共享资源的访问。

  4. 异步回调 :当I/O操作完成时,尽可能使用异步回调来处理I/O结果,以减少对完成端口的轮询。

调试技巧方面,可以使用如Visual Studio这类IDE提供的工具进行性能分析和调试,比如:

  1. CPU分析器 :查看哪些函数占用了大量的CPU时间,可以帮助发现性能瓶颈。

  2. 内存分析器 :确定是否有内存泄漏或其他内存管理问题。

  3. I/O监视器 :查看I/O操作的响应时间和吞吐量,从而优化I/O路径。

  4. 线程调试工具 :观察线程的创建、销毁、同步等行为,以及如何在完成端口之间调度。

通过综合应用以上技术,可以显著提升基于IOCP的程序性能。

3. 异步I/O操作的实践应用

3.1 异步I/O与同步I/O的区别

异步I/O与同步I/O是两种不同的数据处理方式,它们在计算机系统和网络编程中扮演着重要的角色。理解它们之间的差异,对于设计高性能的应用程序至关重要。

3.1.1 同步I/O的局限性

在同步I/O模型中,应用程序必须等待I/O操作完成才能继续执行其他任务。这种模型简单直观,但是它的局限性在处理高并发和长时间I/O操作时变得非常明显。以下是同步I/O的一些关键局限性:

  1. 阻塞行为 :当I/O操作发生时,线程或进程会被阻塞,无法执行其他任何计算或I/O操作,直到当前操作完成。
  2. 资源利用率低 :由于阻塞的存在,CPU的使用效率降低,尤其是在等待慢速设备(如磁盘或网络I/O)时。
  3. 扩展性问题 :在高负载下,同步I/O可能导致大量线程或进程处于等待状态,这会消耗大量系统资源,从而限制了系统的可扩展性。

3.1.2 异步I/O的优势分析

异步I/O模型能够解决同步I/O的一些关键局限性。在异步模型中,I/O操作的发起和完成是分离的。当应用程序发起I/O操作请求时,它会立即得到响应,即使I/O操作尚未完成。以下是异步I/O的一些优势:

  1. 非阻塞操作 :应用程序在I/O操作期间可以继续执行其他任务,包括发起更多的I/O操作。
  2. 提高资源利用率 :由于不需要等待每个I/O操作的完成,CPU和其他系统资源可以更有效地利用。
  3. 提升扩展性 :异步I/O适合于高并发场景,能够支持更多的并发连接,因为它不会因等待I/O完成而占用大量线程或进程。

3.1.3 实践中的选择

在实际应用中,选择同步还是异步I/O模型取决于具体的应用场景。如果I/O操作频率不高,或者对于延迟的容忍度较高,同步I/O可能更为简单和直接。然而,对于高并发或者对实时性要求较高的场景,异步I/O模型提供了更大的优势和更好的性能。

3.2 异步I/O在C++中的实现

3.2.1 利用IOCP实现异步操作

在Windows平台上,I/O完成端口(IOCP)是一种强大的机制,用于实现高效的异步I/O操作。IOCP通过内核对象管理I/O操作,允许应用程序处理多个并发I/O操作而不产生大量线程开销。

示例代码

以下是使用IOCP实现异步读取的基本示例:

#include <windows.h>
#include <iostream>

int main() {
    // 创建IOCP对象
    HANDLE hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    // 假设 hFile 是已打开文件的句柄
    HANDLE hFile = CreateFile("example.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    // 关联文件句柄和IOCP对象
    CreateIoCompletionPort(hFile, hIocp, 0, 0);

    // 初始化 OVERLAPPED 结构
    OVERLAPPED overlapped = {0};
    DWORD bytesRead = 0;

    // 异步读取文件
    BOOL bResult = ReadFile(hFile, buffer, bufferSize, &bytesRead, &overlapped);
    if (!bResult && GetLastError() != ERROR_IO_PENDING) {
        std::cerr << "ReadFile failed with error: " << GetLastError() << std::endl;
        return 1;
    }

    // 等待IOCP完成
    while (GetQueuedCompletionStatus(hIocp, &bytesRead, (PULONG_PTR)&overlapped, (OVERLAPPED **)&lpOverlapped, INFINITE)) {
        // 处理读取的数据
        std::cout << "Data read: " << bytesRead << " bytes" << std::endl;
    }
    // 清理资源...

    return 0;
}
逻辑分析

在上述示例中,我们首先创建了一个IOCP对象和一个文件句柄。然后,我们将文件句柄与IOCP对象关联起来,这是必要的一步,以便后续的异步操作可以被IOCP管理。接着,我们初始化了 OVERLAPPED 结构,并发起了一个异步读取操作。最后,我们使用 GetQueuedCompletionStatus 函数等待I/O操作的完成,并在完成时处理数据。

3.2.2 编写高效的异步处理代码

要编写高效的异步I/O代码,开发者需要关注以下几个方面:

  1. 线程管理 :虽然异步I/O可以减少线程数量,但合理的线程池设计仍然是高效利用系统资源的关键。
  2. 完成端口饱和处理 :当IOCP的完成队列满载时,应有策略避免死锁和性能下降。
  3. 错误处理 :异步编程中的错误处理更为复杂,需要在适当的地方处理各种I/O错误。
  4. 资源管理 :确保在I/O操作完成后,资源得到适当的释放和管理,避免内存泄漏等问题。

3.3 异步通信案例研究

3.3.1 高并发服务器设计

在设计一个高并发服务器时,异步I/O操作是一种常见的解决方案。下面是一个简单的高并发服务器设计案例,展示了如何使用异步I/O来提升性能。

服务器设计概述

服务器将采用异步I/O操作来处理客户端连接和消息。这包括使用IOCP来管理并发的客户端请求,并通过异步读写来实现高效的数据传输。以下为服务器的简化设计步骤:

  1. 初始化IOCP对象 :创建IOCP对象并关联监听套接字。
  2. 接受客户端连接 :使用 AcceptEx 函数异步接受新的连接。
  3. 接收数据 :通过IOCP来接收来自客户端的数据。
  4. 发送响应 :根据接收到的数据,准备并异步发送响应。
  5. 错误处理和资源管理 :确保所有操作完成后进行适当的错误处理和资源管理。

3.3.2 异步回调机制实现

在异步通信中,回调机制是一种常见的实现方式,它允许在I/O操作完成时触发相应的处理代码。

回调函数设计

回调函数在异步操作完成后被调用,开发者可以在此函数中处理I/O操作的结果。对于一个异步I/O操作,回调函数通常包括以下逻辑:

  1. 检查操作状态 :确定操作是否成功,以及错误代码(如果有的话)。
  2. 处理数据 :根据接收到的数据执行进一步的逻辑处理。
  3. 准备下一次操作 :如果需要,准备后续的I/O操作,例如继续接收数据或发送响应。
  4. 资源管理 :确保所有操作完成后,相关资源得到释放。

在设计回调函数时,需要特别注意线程安全和上下文切换的开销,以避免性能瓶颈。

通过本章节的介绍,我们可以看到异步I/O操作在提升系统性能和处理并发连接时所发挥的关键作用。它不仅适用于高性能服务器设计,也成为了实现快速、稳定网络应用的重要基石。在实际开发中,合理地利用异步I/O机制,结合适当的编程模型和设计模式,可以显著提高软件的响应速度和吞吐量。

4. BBTCP5.3库:源代码与应用

BBTCP5.3库是针对C++开发的高性能TCP库,它封装了底层的网络操作,使得开发者可以更方便地实现网络通信功能。在本章节中,我们将深入探讨BBTCP5.3库的源代码,理解其设计架构,并分析其性能表现。

4.1 BBTCP5.3库概述

4.1.1 BBTCP5.3库的功能特点

BBTCP5.3库集成了多种TCP通信场景下的功能需求,提供了简洁而强大的API接口。它支持以下功能特点:

  • 异步IO模型 :通过IOCP实现高效的异步操作,减少线程数量,提高程序性能。
  • 事件驱动机制 :允许开发者以事件驱动的方式编写网络通信程序,简化了编程模型。
  • 连接池管理 :实现自动的连接复用与管理,降低了资源的消耗。
  • 数据加密与压缩 :提供了数据加密和压缩功能,增强了通信的安全性和效率。

4.1.2 BBTCP5.3库的应用场景

BBTCP5.3库特别适用于以下场景:

  • 高并发服务器 :适用于需要处理大量连接的场景,如游戏服务器、即时通讯应用等。
  • 数据采集与分发系统 :如监控系统、日志收集系统等,需要稳定的长连接维持数据传输。
  • 分布式计算 :在分布式计算或存储场景中,可以快速建立安全连接,保证数据传输的可靠性。

4.2 BBTCP5.3库的源代码解析

4.2.1 源代码结构分析

BBTCP5.3的源代码结构非常清晰,主要包括以下几个部分:

  • 核心网络引擎 :负责底层的网络I/O操作,包括数据的发送与接收,以及事件的处理。
  • 事件分发器 :将接收到的事件分发给相应的处理函数,实现了事件驱动机制。
  • 连接池模块 :管理着所有的网络连接,并负责连接的复用和优化资源使用。
  • 加密与压缩模块 :提供数据加密和压缩功能,增强了通信过程的安全性和效率。

4.2.2 核心功能模块的代码解读

BBTCP5.3库的核心功能模块主要围绕异步I/O和事件处理机制展开。下面通过一个简单的代码示例来分析其核心模块的工作原理:

// 假设代码位于 BBTCPConnection.h 文件中
class BBTCPConnection {
public:
    // 处理接收到的数据
    void OnDataReceived(const char* buffer, int length);
    // 连接成功事件处理
    void OnConnected();
    // 连接关闭事件处理
    void OnDisconnected();
    // 发送数据成功事件处理
    void OnDataSent();
    // 错误处理函数
    void OnError(int errorCode);
private:
    // 事件处理函数的映射表
    std::unordered_map<int, std::function<void()>> eventHandlers;
    // ... 其他成员变量和函数 ...
};

// 事件分发器的实现,位于 EventDispatcher.cpp 文件中
void EventDispatcher::DispatchEvent(int eventId, void* data) {
    if(eventHandlers.find(eventId) != eventHandlers.end()) {
        auto handler = eventHandlers[eventId];
        handler();
    }
}

在上述代码中, BBTCPConnection 类负责处理各种网络事件。每个事件类型都对应一个处理函数,这些函数被存储在 eventHandlers 映射表中。当事件发生时, EventDispatcher 调用相应的处理函数来响应事件。

4.3 BBTCP5.3库的性能测试与评估

4.3.1 性能测试方法

为了评估BBTCP5.3库的性能,我们可以采用以下方法:

  • 压力测试 :模拟大量的并发连接,测试在高负载下的稳定性。
  • 延迟测试 :测量消息在客户端和服务器之间往返的延迟时间。
  • 吞吐量测试 :通过发送大量数据,测试最大数据吞吐能力。

4.3.2 库的性能指标分析

根据性能测试结果,我们可以得出BBTCP5.3库的一些关键性能指标:

  • 连接建立时间 :BBTCP5.3库使用异步连接,连接建立时间优于传统同步IO模型。
  • 数据处理速率 :由于IOCP的使用,BBTCP5.3库在数据处理上具备很高的吞吐量,尤其适合高并发场景。
  • 资源占用 :通过连接池管理和事件驱动机制,BBTCP5.3库有效地减少了资源占用,特别是线程资源。

通过深入的源代码解析和性能评估,我们可以看到BBTCP5.3库在设计上注重了效率和易用性。在实际应用中,开发者可以根据业务需求选择合适的功能模块,以实现高效稳定的网络通信应用。

5. TCP协议与网络编程进阶

5.1 TCP协议详解

5.1.1 TCP三次握手和四次挥手

传输控制协议(TCP)是面向连接的、可靠的、基于字节流的传输层通信协议。TCP建立连接的过程叫做三次握手,而终止连接的过程称为四次挥手。

三次握手过程如下:

  1. 客户端发送一个带有SYN(同步序列编号)标志的数据包到服务器。
  2. 服务器端回应客户端的SYN请求,并发送自己的SYN标志包。
  3. 客户端再次发送ACK(确认)标志包,表示连接建立完成。

四次挥手过程如下:

  1. 客户端发送一个FIN(结束)标志的数据包,表示没有数据要发送了。
  2. 服务器端回应一个ACK标志包,然后继续发送剩余数据。
  3. 数据发送完成后,服务器发送FIN标志包,请求关闭连接。
  4. 客户端回应ACK标志包,等待一段时间后连接关闭。

5.1.2 TCP滑动窗口和流量控制

滑动窗口是TCP流量控制的主要机制。它允许发送方在等待确认应答之前发送多个数据包,这样可以有效利用网络带宽,提高数据传输效率。

滑动窗口分为发送窗口和接收窗口:

  • 发送窗口用于控制发送方可以发送数据包的数量。
  • 接收窗口用于控制接收方可以接收的数据包数量。

TCP流量控制通过动态调整窗口大小实现。如果发送方发送数据过快,接收方来不及处理,接收窗口会减小,发送方会减慢发送速率;反之,如果接收方处理很快,接收窗口会增大,允许发送方发送更多的数据。

5.2 高级网络编程技术

5.2.1 非阻塞I/O与事件驱动模型

非阻塞I/O是一种输入输出操作,在I/O操作未完成时,它不会阻塞调用它的线程,而是立即返回,允许程序继续执行其他任务。

事件驱动模型通常与非阻塞I/O一起使用。在这种模型下,当I/O事件发生时,比如数据到达或缓冲区准备好读写,事件会通知相应的处理器进行处理。

现代网络服务器如高性能web服务器和数据库服务器,广泛采用事件驱动模型来处理成千上万的并发连接。

5.2.2 网络协议栈的构建与优化

构建网络协议栈需要对TCP/IP协议栈层次化结构有深入理解,并且需要对网络中的各种协议进行编程实现。

优化网络协议栈主要涉及提高数据包处理效率、减少上下文切换、优化内存管理等方面。例如,在Linux环境下可以通过修改内核参数来优化网络栈性能,如调整TCP连接的最大数量、调整接收窗口大小等。

5.3 网络编程实例与代码实践

5.3.1 实战案例分析

下面是一个基于Linux环境使用socket编程实现TCP服务器的简单实例,该服务器能够接收客户端消息并回显给客户端。

5.3.2 关键代码段的编写与注释

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

int main() {
    int sockfd, newsockfd;
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t clilen = sizeof(cli_addr);

    sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建socket

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(8080);

    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); // 绑定socket到地址

    listen(sockfd, 5); // 监听连接请求

    while (1) {
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); // 接受连接请求

        char buffer[1024];
        int n;
        memset(buffer, '\0', sizeof(buffer));

        n = read(newsockfd, buffer, sizeof(buffer)); // 读取客户端发送的数据
        if (n < 0) error("ERROR reading from socket");
        printf("Here is the message: %s\n", buffer);

        n = write(newsockfd, buffer, strlen(buffer)); // 回显消息给客户端
        if (n < 0) error("ERROR writing to socket");
        close(newsockfd); // 关闭socket
    }
    return 0;
}

在以上代码中,通过创建socket、绑定地址和端口、监听请求、接受连接、读取数据、回显数据以及关闭socket等步骤,展示了一个简单的TCP服务器的工作流程。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文介绍了一个名为BBTCP的C++编写的TCP网络库,版本5.3。该库使用Windows平台特有的IOCP技术,实现高效的异步网络I/O操作。BBTCP的特点包括高性能、代码体积小且易于理解,非常适合初学者学习和实践。文章进一步探讨了TCP协议的基础知识,IOCP的异步I/O模型,以及C++网络编程的要点,包括异步I/O的概念和优势。BBTCP库的完整源代码提供了深入学习和理解网络编程架构和实现细节的机会。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐