当前位置: 首页 > news >正文

C++在实际项目中的应用第二节:C++与网络编程

 

第五章:C++在实际项目中的应用

第二节:C++与网络编程
1. TCP/IP协议详解与C++实现

TCP/IP(传输控制协议/互联网协议)是现代互联网通信的基础协议。理解 TCP/IP 协议对于开发网络应用至关重要。本节将详细介绍 TCP/IP 协议的工作原理以及如何在 C++ 中实现。

1.1 TCP/IP协议栈

TCP/IP 协议栈分为四层:应用层、传输层、网络层和链路层。

  • 应用层:负责处理应用程序之间的通信协议,如 HTTP、FTP 和 SMTP。应用层的协议定义了如何在网络上进行数据交换。

  • 传输层:提供端到端的通信服务,主要有 TCP 和 UDP 两种协议。

    • TCP(传输控制协议):面向连接的协议,提供可靠的数据传输。TCP 通过建立连接、数据流控制和错误检测来确保数据的完整性。
    • UDP(用户数据报协议):无连接的协议,适用于对速度要求高但不需要保证可靠性的应用,如视频流和在线游戏。
  • 网络层:负责数据包的路由和转发,主要协议包括 IP(互联网协议)和 ICMP(互联网控制消息协议)。IP 协议为数据包提供地址和路由信息。

  • 链路层:处理物理网络中的数据传输,包括以太网和无线网络协议。

1.2 TCP连接的建立与关闭

TCP 连接的建立采用三次握手(Three-way Handshake)过程:

  1. SYN:客户端向服务器发送 SYN 数据包,请求建立连接。
  2. SYN-ACK:服务器回复 SYN-ACK 数据包,表示接受连接请求。
  3. ACK:客户端发送 ACK 数据包,完成连接建立。

连接的关闭采用四次挥手(Four-way Handshake)过程:

  1. FIN:客户端发送 FIN 数据包,请求关闭连接。
  2. ACK:服务器回复 ACK 数据包,确认关闭请求。
  3. FIN:服务器发送 FIN 数据包,请求关闭连接。
  4. ACK:客户端回复 ACK 数据包,完成连接关闭。
1.3 C++中TCP/IP的实现

在 C++ 中,我们可以使用 POSIX sockets API 来实现 TCP/IP 通信。以下是一个简单的 TCP 服务器和客户端示例。

TCP服务器示例

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};// 创建套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 绑定套接字if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &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);}// 读取数据read(new_socket, buffer, BUFFER_SIZE);std::cout << "Message received: " << buffer << std::endl;// 关闭套接字close(new_socket);close(server_fd);return 0;
}

TCP客户端示例

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char *message = "Hello from client";// 创建套接字if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {std::cout << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 转换IPv4地址从文本到二进制if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {std::cout << "Invalid address/ Address not supported" << std::endl;return -1;}// 连接到服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {std::cout << "Connection Failed" << std::endl;return -1;}// 发送数据send(sock, message, strlen(message), 0);std::cout << "Message sent" << std::endl;// 关闭套接字close(sock);return 0;
}
2. 实际项目中的网络通信示例

在实际项目中,网络通信经常用于实现客户端与服务器之间的交互。以下是一个简单的聊天室示例,展示了如何使用 C++ 实现多客户端 TCP 聊天功能。

2.1 聊天服务器实现

聊天服务器需要能够处理多个客户端的连接,可以使用 select 函数或多线程来实现。下面是一个简单的多线程聊天室服务器示例。

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <thread>
#include <vector>
#include <mutex>#define PORT 8080
#define BUFFER_SIZE 1024std::vector<int> clients;
std::mutex clients_mutex;void handle_client(int client_socket) {char buffer[BUFFER_SIZE];while (true) {int bytes_read = read(client_socket, buffer, BUFFER_SIZE);if (bytes_read <= 0) {break; // 连接关闭}// 广播消息std::lock_guard<std::mutex> lock(clients_mutex);for (int sock : clients) {if (sock != client_socket) {send(sock, buffer, bytes_read, 0);}}}// 清理客户端{std::lock_guard<std::mutex> lock(clients_mutex);clients.erase(std::remove(clients.begin(), clients.end(), client_socket), clients.end());}close(client_socket);
}int main() {int server_fd;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);// 创建套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 绑定套接字if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &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);}std::cout << "Chat server started on port " << PORT << std::endl;while (true) {int new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);if (new_socket < 0) {perror("accept");continue;}// 添加新客户端{std::lock_guard<std::mutex> lock(clients_mutex);clients.push_back(new_socket);}// 创建新线程处理客户端std::thread(handle_client, new_socket).detach();}close(server_fd);return 0;
}
2.2 聊天客户端实现

聊天客户端负责连接到服务器并发送和接收消息。以下是一个简单的聊天客户端示例。

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <thread>#define PORT 8080
#define BUFFER_SIZE 1024void receive_messages(int sock) {char buffer[BUFFER_SIZE];while (true) {int bytes_read = read(sock, buffer, BUFFER_SIZE);if (bytes_read <= 0) {std::cout << "Disconnected from server." << std::endl;break;}std::cout << "Message received: " << buffer << std::endl;}
}int main() {int sock;struct sockaddr_in serv_addr;// 创建套接字if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {std::cout << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 转换IPv4地址从文本到二进制if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {std::cout << "Invalid address/ Address not supported" << std::endl;return -1;}// 连接到服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {std::cout << "Connection Failed" << std::endl;return -1;}// 启动接收消息的线程std::thread(receive_messages, sock).detach();std::string message;while (true) {std::cout << "Enter message: ";std::getline(std::cin, message);send(sock, message.c_str(), message.size(), 0);}close(sock);return 0;
}
3. 常见问题及解决方案

在网络编程中,我们可能会遇到各种问题。以下是一些常见问题及其解决方案。

3.1 网络延迟与带宽问题

网络延迟会影响应用程序的性能。可以采取以下措施来优化网络延迟:

  • 使用异步 I/O:通过使用异步 I/O 模型,可以提高应用程序的响应速度。
  • 压缩数据:在发送大量数据时,考虑使用数据压缩来减少传输时间。
3.2 连接超时问题

连接超时可能会导致用户体验不佳。可以通过设置合理的超时参数来避免这种情况:

struct timeval timeout;
timeout.tv_sec = 5; // 超时5秒
timeout.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
3.3 安全性问题

网络安全是一个重要的问题。在网络编程中,可以考虑以下安全措施:

  • 加密传输:使用 SSL/TLS 等加密协议来保护数据传输的安全性。
  • 输入验证:对用户输入进行验证,防止 SQL 注入和其他攻击。
3.4 错误处理

在网络编程中,正确的错误处理机制至关重要。以下是一个简单的错误处理示例:

if (send(sock, message.c_str(), message.size(), 0) < 0) {perror("Send failed");close(sock);return -1;
}

以上是关于《C++与网络编程》的详细分析,涵盖了 TCP/IP 协议的实现、实际项目中的网络通信示例,以及常见问题及其解决方案。接下来,我们将总结本章内容。

小结

在本课中,我们深入探讨了 C++ 在网络编程中的应用,包括 TCP/IP 协议的详解与实现、实际项目中的网络通信示例,以及解决常见问题的方法。通过具体的代码示例和项目分析,读者应该能够理解如何在实际项目中有效利用 C++ 进行网络编程。接下来,我们将继续探索更多关于 C++ 的高级话题和实践。

相关文章:

C++在实际项目中的应用第二节:C++与网络编程

第五章&#xff1a;C在实际项目中的应用 第二节&#xff1a;C与网络编程 1. TCP/IP协议详解与C实现 TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;是现代互联网通信的基础协议。理解 TCP/IP 协议对于开发网络应用至关重要。本节将详细介绍 TCP/IP 协议的工作原理以…...

依赖关系是危险的

依赖, 我们需要它们&#xff0c;但如何有效安全地使用它们&#xff1f;在本周的节目中&#xff0c;Kris 与 Ian 和 Johnny 一起讨论了 polyfill.io 供应链攻击、Go 中依赖管理和使用的历史&#xff0c;以及 Go 谚语“一点复制胜过一点依赖”。当然&#xff0c;我们用一些不受欢…...

ipguard与Ping32如何加密数据防止泄露?让企业信息更安全

在信息化时代&#xff0c;数据安全已成为企业运营的重中之重。数据泄露不仅会导致经济损失&#xff0c;还可能损害企业声誉。因此&#xff0c;选择合适的数据加密工具是保护企业敏感信息的关键。本文将对IPGuard与Ping32这两款加密软件进行探讨&#xff0c;了解它们如何有效加密…...

gitlab 的备份与回复

一、gitlab备份 1.确定备份目录 gitlab 默认的备份目录为/var/opt/gitlab/backups&#xff0c;可通过配置gitlab.rb配置文件进行修改&#xff0c;如&#xff1a; [rootlocalhost ~]# vim /etc/gitlab/gitlab.rb #若要修改备份文件的存储目录话&#xff0c;打开下面选项的注释…...

创建型模式-----建造者模式

目录 背景&#xff1a; 构建模式UML 代码示例 房子成品&#xff1a; 构建器抽象&#xff1a; 具体构建器&#xff1a; 建筑师&#xff1a; 测试部…...

威胁 Windows 和 Linux 系统的新型跨平台勒索软件:Cicada3301

近年来&#xff0c;网络犯罪世界出现了新的、日益复杂的威胁&#xff0c;能够影响广泛的目标。 这一领域最令人担忧的新功能之一是Cicada3301勒索软件&#xff0c;最近由几位网络安全专家进行了分析。他们有机会采访了这一危险威胁背后的勒索软件团伙的成员。 Cicada3301的崛…...

Go 语言基础教程:7.Switch 语句

在这篇教程中&#xff0c;我们将学习 Go 语言中的 switch 语句&#xff0c;它是条件分支的重要结构。我们将通过一个示例程序逐步解析 switch 的不同用法。 package mainimport ("fmt""time" )func main() {i : 2fmt.Print("Write ", i, " …...

mysql原理、部署mysql主从+读写分离、监控mysql主从脚本

mysql&#xff1a;工作原理 从库生成两个线程&#xff0c;一个I/O线程&#xff0c;一个SQL线程&#xff1b; i/o线程去请求主库 的binlog&#xff0c;并将得到的binlog日志写到relay log&#xff08;中继日志&#xff09; 文件中&#xff1b; 主库会生成一个 log dump 线程&…...

模型选择拟合

1.通过多项式拟合交互探索概念 import math import numpy as np import torch from torch import nn from d2l import torch as d2l 2.使用三阶多项式来生成训练和测试数据的标签 max_degree 20 # 多项式的最大阶数 n_train, n_test 100, 100 # 训练和测试数据集大小 true…...

文案语音图片视频管理分析系统-视频矩阵

文案语音图片视频管理分析系统-视频矩阵 1.产品介绍 产品介绍方案 产品名称&#xff1a; 智驭视频矩阵深度分析系统&#xff08;SmartVMatrix&#xff09; 主要功能&#xff1a; 深度学习驱动的视频内容分析多源视频整合与智能分类高效视频检索与编辑实时视频监控与异常预警…...

ArcGIS计算落入面图层中的线的长度或面的面积

本文介绍在ArcMap软件中&#xff0c;计算落入某个指定矢量面图层中的另一个线图层的长度、面图层的面积等指标的方法。 如下图所示&#xff0c;现在有2个矢量要素集&#xff0c;其中一个为面要素&#xff0c;表示某些区域&#xff1b;另一个为线要素&#xff0c;表示道路路网。…...

ctfshow-web入门-web172

//拼接sql语句查找指定ID用户 $sql "select username,password from ctfshow_user2 where username !flag and id ".$_GET[id]." limit 1;"; 联合查询 该题目与上一个题目不是同一个类型&#xff0c;该题目需要进行sql联合查询。 第一步&#xff1a;确…...

Keep健身TV版 3.3.0 | 针对智能电视的健身塑形软件

Keep健身TV版是专为智能电视设计的功能强大的健身塑形软件。该软件根据用户的不同需求提供多种器械和阶段健身目标组合编排&#xff0c;为用户提供科学、规范、专业的实时指导。即便是在家没有健身器械的情况下&#xff0c;也能跟随教练的语音指导一步步完成训练。软件涵盖从有…...

推荐一些关于计算机网络和 TCP/IP 协议的书籍

以下是一些关于计算机网络和 TCP/IP 协议的优秀书籍推荐: 《TCP/IP 详解》: 作者为 W.Richard Stevens,这是一套经典之作,分为三卷。《TCP/IP 详解卷 1:协议》:详细解析了 TCP/IP 协议的工作原理和实现细节,对协议族中的各个层次和协议,如 IP、TCP、UDP 等进行了深入剖…...

生成式AI浪潮下的商业机遇与经济展望 —— 与互联网时代的比较

一、引言 近年来,生成式人工智能(AI)技术迅速崛起,不仅吸引了大量资本的关注,同时也催生了诸多创新商业模式。与互联网早期阶段类似,AI领域同样面临着前所未有的发展机遇。本文将探讨生成式AI与互联网时代的异同,并分析当前AI行业的经济状况及其增长潜力。 二、经济形…...

Go 标准库

本篇内容是根据2016年9月份The Go Standard Library音频录制内容的整理与翻译, BoltDB 的创建者 Ben Johnson 参加了节目&#xff0c;讨论 NoSQL 与 SQL 数据库、两者之间的权衡以及选择其中之一。我们还讨论了 Ben 的数据秘密生活项目&#xff0c;可视化数据结构&#xff0c;…...

AUTOSAR_EXP_ARAComAPI的6章笔记(5)

☞返回总目录 相关总结&#xff1a;AUTOSAR 通信组的使用方法总结 6.5 通信组的使用方法 6.5.1. 设置 本节描述了使用 Communication Group Template&#xff08;类别为 COMMUNICATION_GROUP&#xff09;定义通信组的配置步骤。定义一个通信组需要指定三个项目&#xff1a;…...

Photoshop中的混合模式公式详解

图层混合简介 图层混合&#xff08;blend&#xff09;顾名思义&#xff0c;就是把两个图层混合成一个。 最基本的混合是alpha融合&#xff08;alpha compositing&#xff09;&#xff0c;这是一个遵循光的反射与透射等&#xff08;简化版&#xff09;物理学原理的混合方式。 各…...

Vue 自定义指令 Directive 的高级使用与最佳实践

前言 Vue.js 是一个非常流行的前端框架&#xff0c;它的核心理念是通过声明式的方式来描述 UI 和数据绑定。除了模板语法和组件系统&#xff0c;Vue 还提供了一个强大的功能——自定义指令。 自定义指令可以让我们对 DOM 元素进行底层操作&#xff0c;下面让我们通过一个有趣的…...

万字图文实战:从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL&#xff08;Software OpenGL&#xff09;‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式&#xff08;包括几何处理、光栅化、着色等&#xff09;&#xff0c;不依赖GPU硬件加速。这种模式通常性能较低&#xff0c;但兼容性极强&#xff0c;常用于不支持硬件加速…...

大模型智能体核心技术:CoT与ReAct深度解析

**导读&#xff1a;**在当今AI技术快速发展的背景下&#xff0c;大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术&#xff1a;CoT&#xff08;思维链&#xff09;和ReAct&#xff08;推理与行动&#xff09;&#xff0c;这两种方法正在重新定义大模…...

DriveGPT4: Interpretable End-to-end Autonomous Driving via Large Language Model

一、研究背景与创新点 (一)现有方法的局限性 当前智驾系统面临两大核心挑战:一是长尾问题,即系统在遇到新场景时可能失效,例如突发交通状况或非常规道路环境;二是可解释性问题,传统方法无法解释智驾系统的决策过程,用户难以理解车辆行为的依据。传统语言模型(如 BERT…...

触发DMA传输错误中断问题排查

在STM32项目中&#xff0c;集成BLE模块后触发DMA传输错误中断&#xff08;DMA2_Stream1_IRQHandler进入错误流程&#xff09;&#xff0c;但单独运行BLE模块时正常&#xff0c;表明问题可能源于原有线程与BLE模块的交互冲突。以下是逐步排查与解决方案&#xff1a; 一、问题根源…...