Linux 系统 recv() 函数详解102


简介

recv() 函数是 Linux 系统中用于从网络套接字中读取数据的系统调用。它可以从 TCP 套接字或 UDP 套接字读取数据,是网络编程中常用的函数之一。

函数原型

recv() 函数的原型如下:```c
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
```

sockfd:要读取数据的套接字描述符。
buf:一个指向缓冲区的指针,其中将存储读取的数据。
len:缓冲区的大小,以字节为单位。
flags:指定读取操作标志。

返回值

如果成功,recv() 函数将返回读取的字节数。如果套接字处于非阻塞模式并且没有数据可读,则函数将返回 -1,并且 errno 设置为 EAGAIN 或 EWOULDBLOCK。如果发生错误,recv() 函数将返回 -1,并且 errno 设置为适当的错误代码。

flags 标志

flags 参数可以指定以下标志:

- MSG_WAITALL:等待读取所有请求的字节。如果没有收到所有字节,则函数将阻塞直到收到所有字节或发生错误。

- MSG_DONTWAIT:如果套接字处于非阻塞模式,则设置此标志允许函数在没有数据可读时立即返回 -1,并且 errno 设置为 EAGAIN 或 EWOULDBLOCK。

- MSG_PEEK:获取套接字缓冲区中的数据,但不会从缓冲区中删除数据。

数据接收

当成功从套接字读取数据时,recv() 函数会将数据存储在 buf 缓冲区中。读取的字节数可以通过函数的返回值获得。如果读取的数据量大于 buf 的大小,则会截断多余的数据。

套接字类型

recv() 函数可以用于 TCP 套接字和 UDP 套接字。对于 TCP 套接字,recv() 函数将阻塞直到接收到数据或发生错误。对于 UDP 套接字,recv() 函数将立即返回,无论套接字缓冲区中是否有数据。

示例代码

以下示例代码展示了如何使用 recv() 函数从 TCP 套接字读取数据:```c
#include
#include
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return -1;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
close(sockfd);
return -1;
}
if (listen(sockfd, 5) < 0) {
perror("listen");
close(sockfd);
return -1;
}
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_sockfd < 0) {
perror("accept");
close(sockfd);
return -1;
}
char buf[1024];
ssize_t nbytes = recv(client_sockfd, buf, sizeof(buf), 0);
if (nbytes < 0) {
perror("recv");
close(client_sockfd);
close(sockfd);
return -1;
}
printf("Received %zd bytes: %s", nbytes, buf);
close(client_sockfd);
close(sockfd);
return 0;
}
```

2025-01-18


上一篇:iOS 操作系统:优点与缺点

下一篇:Android 身份录入系统:深入探讨