c++ linux recv的概念和使用案例(服务端和客户端都有)

devtools/2025/2/7 5:56:57/

recv函数是用于接收数据的socket函数,在C++ Linux环境中扮演着关键角色。其原型如下:

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数说明:

  • sockfdsocket描述符,标识要接收数据的socket
  • buf: 指向用于存储接收数据的缓冲区的指针。
  • len: 缓冲区的长度,指定最多可以接收的字节数。
  • flags: 接收标志,用于控制接收行为,常用的标志包括:
    • MSG_PEEK: 查看数据而不移除它们。
    • MSG_OOB: 接收带外数据。
    • MSG_WAITALL: 等待直到接收完指定数量的数据或发生错误。
      返回值:
  • 成功时返回实际接收的字节数。
  • 返回-1表示发生错误。
  • 返回0表示对方关闭了连接。
    使用案例:
    以下是服务端和客户端使用recv函数的示例代码。
    服务器端代码:
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <string>
#include <csignal>
#include <thread>
#include <vector>
std::vector<std::thread> threads;
// 信号处理函数
void signal_handler(int sig) {std::cout << "Server shutting down..." << std::endl;close(sockfd);// 等待所有线程完成for (auto &t : threads) {if (t.joinable()) {t.join();}}exit(0);
}
// 处理客户端连接的函数
void handle_client(int client_sock) {std::string buffer;buffer.resize(1024);ssize_t bytes_received = recv(client_sock, &buffer[0], buffer.size(), 0);if (bytes_received < 0) {std::cerr << "Error receiving data" << std::endl;} else if (bytes_received == 0) {std::cout << "Client disconnected" << std::endl;} else {buffer.resize(bytes_received);std::cout << "Received from client: " << buffer << std::endl;// 发送响应const char *response = "Hello, Client!";ssize_t bytes_sent = send(client_sock, response, strlen(response), 0);if (bytes_sent < 0) {std::cerr << "Error sending data" << std::endl;}}// 关闭连接close(client_sock);
}
int main() {// 注册信号处理函数std::signal(SIGINT, signal_handler);// 创建socketint sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {std::cerr << "Error creating socket" << std::endl;return -1;}// 绑定socket到端口8080struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080);server_addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {std::cerr << "Error binding socket" << std::endl;close(sockfd);return -1;}// 监听连接,最大连接数为5if (listen(sockfd, 5) < 0) {std::cerr << "Error listening on socket" << std::endl;close(sockfd);return -1;}std::cout << "Server listening on port 8080..." << std::endl;while (true) {// 接受连接struct sockaddr_in client_addr;socklen_t client_len = sizeof(client_addr);int client_sock = accept(sockfd, (struct sockaddr *)&client_addr, &client_len);if (client_sock < 0) {std::cerr << "Error accepting connection" << std::endl;continue;}std::cout << "Client connected" << std::endl;// 创建线程处理客户端连接threads.emplace_back(handle_client, client_sock);threads.back().detach();}// 关闭socketclose(sockfd);return 0;
}

客户端代码:

#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <string>
#include <csignal>
// 信号处理函数
void signal_handler(int sig) {std::cout << "Client shutting down..." << std::endl;close(sockfd);exit(0);
}
int main() {// 注册信号处理函数std::signal(SIGINT, signal_handler);// 创建socketint sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {std::cerr << "Error creating socket" << std::endl;return -1;}// 连接到服务器struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {std::cerr << "Error connecting to server" << std::endl;close(sockfd);return -1;}std::cout << "Connected to server" << std::endl;// 发送数据const char *message = "Hello, Server!";ssize_t bytes_sent = send(sockfd, message, strlen(message), 0);if (bytes_sent < 0) {std::cerr << "Error sending data" << std::endl;}// 接收响应std::string buffer;buffer.resize(1024);ssize_t bytes_received = recv(sockfd, &buffer[0], buffer.size(), 0);if (bytes_received < 0) {std::cerr << "Error receiving data" << std::endl;} else if (bytes_received == 0) {std::cout << "Server disconnected" << std::endl;} else {buffer.resize(bytes_received);std::cout << "Received from server: " << buffer << std::endl;}// 关闭连接close(sockfd);return 0;
}

总结:
recv函数在C++ Linux环境中用于接收socket连接中的数据,是实现客户端-服务器通信的关键函数之一。通过结合socketbindlistenacceptsendrecv等函数,可以构建功能完善的网络应用程序。在实际应用中,需要注意错误处理、线程安全以及资源释放等问题,以确保程序的 robustness 和可靠性。
[
\boxed{recv函数是用于接收数据的socket函数,原型为ssize_t recv(int sockfd, void *buf, size_t len, int flags);。它在服务端和客户端的通信中扮演着 crucial的角色,用于接收对方发送的数据。通过结合其他socket函数,可以实现完整的客户端-服务器通信。}
]


http://www.ppmy.cn/devtools/156732.html

相关文章

ubuntu下迁移docker文件夹

在 Ubuntu 系统中迁移 Docker 文件夹&#xff08;如 Docker 数据存储文件夹 /var/lib/docker&#xff09;到另一个磁盘或目录&#xff0c;通常是为了释放系统盘空间。以下是迁移过程的详细步骤&#xff1a; 1. 停止 Docker 服务 在进行迁移之前&#xff0c;必须停止 Docker 服…

ROS2从入门到精通3-1:详解urdf语法并自定义机器人

目录 0 专栏介绍1 urdf文件是什么?2 urdf基本语法2.1 robot标签2.2 link标签2.2.1 visual标签2.2.2 collision标签2.2.3 inertial标签2.3 joint标签3 案例一:分别生成球体的机器人部件4 案例二:自定义机器人5 附录:常用工具5.1 检查urdf语法5.2 可视化urdf0 专栏介绍 本专…

交易一张股指期货需要多少钱?

咱们先来说说交易一张股指期货得花多少钱。这个其实挺简单的&#xff0c;就是用一个公式来算&#xff1a;股指期货保证金合约价值&#xff08;指数点位合约乘数&#xff09;保证金比例交易手数。 举个例子&#xff0c;假设沪深300股指期货的指数点位是3842.22点&#xff0c;合…

低空经济:推动「进城载人,跨界融合」成为2025年新的探索方向

2024年是低空经济元年&#xff0c;它成为各大平台热搜的常客&#xff0c;也成为人们茶余饭后的谈资&#xff0c;更是各区域争先恐后抢占的新赛道。 2025年&#xff0c;各地必然要加强低空基础设施建设&#xff0c;在此之余&#xff0c;推动低空经济「进城载人&#xff0c;跨界…

简单的回调函数理解

使用两个脚本简单理解回调函数。简单来说&#xff0c;将函数B当做另一个函数A的参数进行调用。 Demo1 使用当前通用的std::function<>形式和std::bind形式。 #include <iostream> #include <functional> // 包含 std::function 和 std::bindusing namespac…

PCL 最小包围圆(二维)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 最小包围圆是指能够包含给定点集中所有点的最小圆。这个算法通常用于计算几何、计算机图形学、机器学习等领域。以下是该算法的基本原理和实现流程: 1. 初始化:将点集中的所有点加入待处理列表。 2. 查找最远点:…

利用HTML和css技术编写学校官网页面

目录 一&#xff0c;图例展示 二&#xff0c;代码说明 1&#xff0c;html部分&#xff1a; 【第一张图片】 【第二张图片】 【第三张图片】 2&#xff0c;css部分&#xff1a; 【第一张图片】 【第二张图片】 【第三张图片】 三&#xff0c;程序代码 一&#xff0c;…

GEE | 2000年至今MODIS蒸散发ET变化分析 (日/月/季节/年)

一、说明 MOD16A2.061是基于Penman-Monteith方程的8天复合蒸散量产品&#xff0c;空间分辨率为500米&#xff0c;时间范围自2001年起至今。基于GEE对ET进行时间变化分析&#xff0c;包括日、月、季节和年&#xff0c;并导出对应的栅格数据。 各位同学可以根据需求更改研究区、…