I'm trying to write a server in C, with I/O non-blocking because sometimes it goes down for flood requests. Looking around, I've notice that I/O non-blocking can solve my problem. Reading the Beej guide, I've implemented the recvtimeout function, that set a timeout to handle data from a client. People told me I have to use the select to avoid this problem, but I used it already in the function recvtimeout:
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);
}
So, I've added a piece of code that show me if NONBLOCK is set or not, but never I read nonblocking active, so in my code nonblocking is not active. How can I mod my code to enable this?
The problem is when I read a string from a client and have a code like this:
char headerstring[512];
memset(headerstring,0,512);
if(this->recvtimeout(client_fd,headerstring,sizeof(headerstring),10) < 0){
close(client_fd);
}
All works fine, but with a flooder that close the connection during the transaction, the server goes down. I've tried try-catch and any other things...but nothing.