Read Blocker in C

Asked

Viewed 407 times

0

I am trying to make a server in C. After receiving the client’s connection the objective is to wait for information from the client in the socket, for this I use the following code.

/*Read Messages*/
        close(fd);
        nread = read(fd, msg, BUFFERSIZE-1);
        close(fd);
        msg[nread] = '\0';
        printf("%s\n", msg);

The function close(fd) will close/clear the socket before reading. But the problem happens in reading, read(). My question is whether the close(fd) are correctly placed and whether this is the consequence of read junk-reading.

  • 1

    Well, this close-up shouldn’t even be there either. It would be good for you to start from a code that already works, and adapt to its use gradually. In any case, I edited my reply to try to be more comprehensive.

2 answers

4

This statement is not always true: "As everyone knows the read of a socket is blocking, IE, always waiting for information in the socket."

A socket may or may not be "blocking", it merely depends on setting this property in the stream.

What may be happening, in your case, is the read is blocking, but when receiving new data, it usually returns the value and exits the lock state (this is expected).

Try using something like the following code to evaluate what’s going through your stream, to see if the correct data is coming in, and if what you’re receiving is control data and/or special characters (remember to put some criteria in the code to exit the infinite loop, if there is no way to break the code ;) ).

while ((numread = read(sock_fd, &buff, 1)) > 0) {
   write(out_fd, &buff, 1);
}

Here is a function that serves to configure the blocking behavior in both linux and windows:

#import <fcntl.h>

/** Retorna true se funcionou, ou false se houve algum erro
  * fd é o file descriptor em que for aplicar o parâmetro
  * blocking é true ou false, definindo se o socket vai ser "bloqueante" ou não
  */
bool SetSocketBlockingEnabled(int fd, bool blocking)
{
   if (fd < 0) return false;

#ifdef WIN32
   unsigned long mode = blocking ? 0 : 1;
   return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? true : false;
#else
   int flags = fcntl(fd, F_GETFL, 0);
   if (flags < 0) return false;
   flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK);
   return (fcntl(fd, F_SETFL, flags) == 0) ? true : false;
#endif
}

Original code in this reply by Soen

  • I’m being duped at university then, but either way this is one of the solutions to avoid garbage in the socket?

  • Try to edit the question to reflect exactly what you need, and give more details about the garbage problem, so that I or someone else can help you better. It may even have to do with the trash the fact that your function is leaving where it should block. Maybe if you can put the most complete code, make it easy. Anyway, the function serves to make you sure of the state of the stream.

0


When the server accepts a client, it creates a process or thread that is in charge of working with that client. Before handing over work to this process, we close the fd of the customer. For example:

while (1) {
     client = accept(fd,(struct sockaddr *)&client_addr,&client_addr_size);
     if (client > 0) {
        if (fork() == 0) {
            close(fd);
            process_client(client);
            exit(0);
        }
    close(client);
    }
}

The function process_client will be the worker process. That is, the function is in charge of waiting for information in the socket.

void process_client(int client_fd)
{
    int nread = 0;
    char buffer[BUF_SIZE];
    nread = read(client_fd, buffer, BUF_SIZE-1);
    buffer[nread] = '\0';
    printf("%s", buffer);
    fflush(stdout);
    close(client_fd);
}

If the goal is to always be waiting for information in the client’s socket just put the whole function in a cycle While(1)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.