O_NONBLOCK 后 recv 一直返回1
时间: 2023-10-27 09:06:23 浏览: 54
O_NONBLOCK 是一个文件描述符标志,它表示在读取或写入时不会阻塞进程。recv 函数在使用 O_NONBLOCK 标志时,如果没有数据可读,会立即返回,返回值为 1 表示读取了一个字节的数据。这种情况下,应该在循环中不断调用 recv 函数,直到返回值为 0 表示连接已关闭,或者返回值为 -1 并且 errno 为 EAGAIN 或 EWOULDBLOCK 表示暂时没有数据可读,需要等待。需要注意的是,使用 O_NONBLOCK 标志时需要特别小心,因为它可能会导致一些问题,比如数据丢失或者粘包等。
相关问题
rust中的channel创建的句柄有没有O_NONBLOCK属性
在Rust中,channel创建的句柄默认是阻塞的,没有O_NONBLOCK属性。如果需要使用非阻塞模式,可以使用tokio库提供的异步通道。tokio库中提供了两种异步通道:mpsc和oneshot。这两种通道都支持非阻塞模式。可以在创建通道时设置non_blocking选项为true来启用非阻塞模式。例如:
```rust
use tokio::sync::mpsc;
let (tx, rx) = mpsc::channel::<String>(32);
tx.send("hello".to_string()).await.unwrap();
let mut rx = rx.recv();
match rx.poll() {
Poll::Ready(Some(msg)) => println!("Received message: {}", msg),
Poll::Pending => println!("Channel is empty"),
Poll::Ready(None) => panic!("Channel has been closed"),
}
```
在上面的代码中,我们使用tokio的mpsc通道创建了一个非阻塞的发送和接收端。在接收端,我们使用poll方法来检查通道是否有消息。如果通道为空,poll方法会返回Pending。如果通道中有消息,poll方法会返回Ready(Some(msg))。如果通道已经关闭,poll方法会返回Ready(None)。
recv非阻塞,用C语言写出程序
下面是一个简单的C语言程序,使用非阻塞模式进行recv操作:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
int main() {
int sock;
struct sockaddr_in server_addr;
char buffer[1024];
int bytes_received;
int flags;
// 创建socket
sock = socket(AF_INET, SOCK_STREAM, 0);
// 设置socket为非阻塞模式
flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
// 连接服务器
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
// 循环读取数据
while (1) {
bytes_received = recv(sock, buffer, sizeof(buffer), 0);
if (bytes_received == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
// 没有数据可读,继续循环
continue;
} else {
// 其他错误,退出循环
perror("recv error");
break;
}
} else if (bytes_received == 0) {
// 连接关闭,退出循环
printf("connection closed by peer\n");
break;
} else {
// 成功读取数据,处理数据
buffer[bytes_received] = '\0';
printf("received: %s\n", buffer);
}
}
// 关闭socket
close(sock);
return 0;
}
```
该程序使用了fcntl函数将socket设置为非阻塞模式,然后循环调用recv函数读取数据。如果recv返回EWOULDBLOCK或者EAGAIN错误码,说明当前没有数据可读,需要继续循环。如果recv返回其他错误码,或者返回0表示连接关闭,就退出循环。如果成功读取到数据,就处理数据并继续循环。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)