c - 如何修改recv来实现IO/非阻塞?

标签 c nonblocking asyncsocket recv

我正在尝试用 C 语言编写一个 I/O 非阻塞的服务器,因为有时它会因洪水请求而崩溃。 环顾四周,我发现 I/O 非阻塞可以解决我的问题。 阅读 Beej 指南,我实现了 recvtimeout 函数,该函数设置超时来处理来自客户端的数据。 人们告诉我我必须使用 select 来避免这个问题,但我已经在函数 receivetimeout 中使用了它:

int Server::recvtimeout(int s, char *buf, int len, int timeout)
    {

    //Check if non-blocking
    fcntl(s, F_SETFL, O_NONBLOCK);
int flags = fcntl(s, F_GETFD);
if ((flags & O_NONBLOCK) == O_NONBLOCK) {
  fprintf(stderr, "nonblocking active");
}
else {
  fprintf(stderr, "nonblocking not active");
}
    //End check

fd_set fds;
int n;
struct timeval tv;
// set up the file descriptor set
FD_ZERO(&fds);
FD_SET(s, &fds);
// set up the struct timeval for the timeout
tv.tv_sec = timeout;
tv.tv_usec = 0;
// wait until timeout or data received
n = select(s+1, &fds, NULL, NULL, &tv);
if (n == 0){
    return -2; // timeout!
}
if (n == -1){
    return -1; // error
}
// data must be here, so do a normal recv()
return recv(s, buf, len, 0);
    }

因此,我添加了一段代码来显示 NONBLOCK 是否已设置,但我从未读过“非阻塞事件”,因此在我的代码中,非阻塞未处于事件状态。 如何修改我的代码以启用此功能?

问题是当我从客户端读取字符串并有如下代码时:

        char headerstring[512];
    memset(headerstring,0,512);
    if(this->recvtimeout(client_fd,headerstring,sizeof(headerstring),10) < 0){
        close(client_fd);
    }

一切工作正常,但是如果洪水泛滥者在事务期间关闭连接,服务器就会崩溃。 我尝试过 try-catch 和其他任何东西......但什么也没有。

最佳答案

将套接字设置为非阻塞的正常方法是

  int x;
  x=fcntl(s,F_GETFL,0);
  fcntl(s,F_SETFL,x | O_NONBLOCK);

在您的代码中,您将使用

获取标志
int flags = fcntl(s, F_GETFD);

而你应该这样做

  x=fcntl(s,F_GETFL,0);

因此,您的套接字实际上可能启用了非阻塞。

关于c - 如何修改recv来实现IO/非阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10803079/

相关文章:

c++ - 用于解析 C 和 C++ 声明的螺旋规则和 'declaration follows usage'

c - c中是否有任何运算符可以避免在第一次赋值后变量值发生任何变化?

c - 我的程序在调试器中运行良好,但在发布中运行不佳

python - PyAudio 响应式录音

objective-c - 并行 TCP 连接的数据传输速度较慢

c - Linux共享内存: shmget() vs mmap()?

java - 下面CompletableFuture示例中join的调用是否会阻塞进程

c# - 在任何给定时间使用 C# 中的异步套接字将消息发送回客户端列​​表

c++ - boost::async_write 导致数据损坏