Yosef Alon
Yosef Alon

Reputation: 78

Socket - sending a big string in c

I am trying to understand why my function dosnt sending the all string (Its send only 53576 elements from 365568: This is the function I am using in the client side:

#define DATASIZEBUFFER 4000// 365568
void DieWithError(char *errorMessage);/* Error handling function */


void TcpClient ( char *servIP , unsigned short echoServPort , Hash_t *HashData)//(int argc, char *argv[])
{
int sock;                           //Socket descriptor 
struct sockaddr_in ServAddr;    //Echo server address            
int bytesRcvd, totalBytesRcvd;      //Bytes read in single recv()
                                    //and total bytes read      

// Create a reliable, stream socket using TCP 
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    DieWithError(" socket () failed") ;

// Construct the server address structure 
memset(&ServAddr, 0, sizeof(ServAddr));  /* Zero out structure */
ServAddr.sin_family = AF_INET;               /* Internet address family */
ServAddr.sin_addr.s_addr = inet_addr(servIP);/* Server IP address */
ServAddr.sin_port = htons(echoServPort);    /* Server port */

// Establish the connection to the server 
if (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
    DieWithError(" connect () failed") ;
for (;;)
{
// Send the string to the server //

    if (send(sock, HashData->array , HashData->elementNumber, 0) != HashData->elementNumber)
    {
        printf ("Bytes Nedded to recived: %ld\nAnd (DATASIZEBUFFER) is %d\n", HashData->elementNumber , DATASIZEBUFFER);
        DieWithError("send() sent a different number of bytes than expected");
    }
}

Upvotes: 1

Views: 2397

Answers (1)

Arun
Arun

Reputation: 20403

send() does not guarantee that it would send all the data.

From send man page:

   On success, these calls return the number of bytes sent.  On error,
   -1 is returned, and errno is set appropriately.

You can write a loop around send() and invoke it multiple times until all data is sent (or, error is returned). It could be something like the following (please modify it based on your needs):

size_t 
Send(int sockfd, const void *buf, size_t len, int flag) {
  size_t sent_total = 0;
  for (int sent_now = 0; sent_total != len; sent_total += sent_now) {
    sent_now = send(sockfd, buf + sent_total, len - sent_total, flag);
    if (sent_now == -1) break;
  }
  if (sent_total != len) {
    LOG("send requested = %zu, sent = %zu", len, sent_total);
  }
  return sent_total;
}

Update to address @Myst's comments:

Although the question did not mention it explicitly, I assumed that the sockets used are blocking, since there are no fcntl call. With that in mind, the following from send() man page explains the situation:

   When the message does not fit into the send buffer of the socket,
   send() normally blocks, unless the socket has been placed in
   nonblocking I/O mode. 

   In nonblocking mode it would fail with the
   error EAGAIN or EWOULDBLOCK in this case.  The select(2) call may be
   used to determine when it is possible to send more data.

For non-blocking socket, the design need to be different and is outside the scope of this discussion.

Upvotes: 7

Related Questions