Stefano Belli
Stefano Belli

Reputation: 15

read() or write() functions are not working

I am trying to send data / read data from socket fds with

write() and read() functions.

The problem is that one of them are not working correctly, I explain:

write() sends data to "sockfd" -> "sockfd" inserts data to "answer" variable with read() function

the problem is that when I try to get the content of answer (with the usual printf("%s\n",answer) ), it is empty.

I don't know if the problem comes from read() or write(), if both of them fail, they return -1 so I added a simple check to see if one of them return < 0.

Below the code:

This one is the sender, problem comes with the last write() call [This: if (write(client_sockfd,denied,sizeof(denied)) < 0)]

                                if(login_required(client_ipaddr) == 1)
                                {
                                  char getpasswd[256];
                                  char auth[256]="auth-required";
                                  char granted[9]="granted";
                                  char denied[7]="denied";
                                  //checks that password file exists!
                                  //check_passwd_file("passfile",client_sockfd);
                                  log_string("[CLIENT-AUTH]Authentication required! ...");
                                  write(client_sockfd,auth,sizeof(auth));
                                  read(client_sockfd,getpasswd,sizeof(getpasswd));
                                  //log_string(getpasswd);
                                  //check here
                                  if(strcmp(getpasswd,"jasmtest") == 0)
                                  {
                                    log_string("[PWD][OK]Password accepted!\n");
                                    log_string("[PWD][OK]Authorized!\n");
                                  }     
                                  else if(strcmp(getpasswd,"jasmtest") != 0)
                                  {
                                     log_error("[PWD][DEN]Wrong password!\n");
                                     log_error("[PWD][DEN]Closing connection...\n");
                                     if (write(client_sockfd,denied,sizeof(denied)) < 0)
                                       log_error("[core/ipc.c][start_server()][getpasswd][write()] ERROR while sending denied\n");
                                  }
                                }
                                else
                                {
                                  write(client_sockfd,not_required,sizeof(not_required));
                                  log_string("[CLIENT-AUTH]Authentication NOT required!");
                                }

Here is the "client" I explain: until write(sockfd,get_my_pass,sizeof(get_my_pass)); all is working, when i call: read(sockfd,answer,sizeof(answer)) it is not working anymore as I described above.

read(sockfd,get_msg_from_server,255);

        if(strcmp(get_msg_from_server, "auth-required") == 0)
        {
          printf("+-----------------------------------------------------------------------+\n");
          printf("* Authentication is required before accessing JASM Command Line Interface\n");
          printf("* Password: \n");

          write(sockfd,get_my_pass,sizeof(get_my_pass));
          if(read(sockfd,answer,sizeof(answer)) < 0)
           printf("* Error on read\n");

          if(strcmp(answer,"denied") == 0)
          {
              printf("* Non-authorized access!!\n");
              printf("* Exiting...\n");
              close(sockfd);
              exit(3);
          }

        }
        else if(strcmp(get_msg_from_server, "auth-not-required") == 0)
          printf("* Authentication is not required for this session\n");

Thanks to all of u :)

Upvotes: 1

Views: 1897

Answers (1)

John Bollinger
John Bollinger

Reputation: 181932

For the most part, you do not check the return values of your read() and write() calls. This is always an error if you are transferring more than one byte, for even if no I/O error occurs, these functions are in no way guaranteed to transfer the specified number of bytes. That number gives the maximum that will be transferred; you need to be prepared to transfer the desired bytes over multiple calls.

Moreover, it follows that in most cases you need some kind of protocol by which each reader can predict how many bytes to expect to read. If you're sending fixed-length messages then writer and reader must agree on message length; if you're sending variable-length messages then you need either a per-message explicit message length (itself a fixed-length component) or a message terminator that the reader can recognize.

Your case is somewhat illustrative. This write by the server:

write(client_sockfd,auth,sizeof(auth));

seems intended to be paired with this read by the client:

read(sockfd,get_msg_from_server,255);

Note, however, that auth is declared as char auth[256], so its size is 256. Supposing that the server indeed writes all 256 bytes (which as I said, is not guaranteed), the client reads at most 255 of them, leaving at least one waiting, unread. The next read (into answer) will start at that unread byte. It will be a 0 (given the initializer provided for auth), therefore answer will be interpreted an empty string, notwithstanding whatever bytes may follow that initial '\0'.

Indeed, even if the server successfully transfers fewer than 256 bytes, if it transfers even one more than enough for the client to recognize the message as containing the string "auth-required" then the next byte the client reads will always have value zero.

Upvotes: 2

Related Questions