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