SO_SNDTIMEO in setsockopt() doesn't work in send()

I create a program that need a timeout on both send() and recv() function, but I found that SO_SNDTIMEO doesn't work but SO_RCVTIMEO works!!

     int sock;
     int bytesRcvd, totalBytesRcvd = 0;
     struct sockaddr_in servAddr;
     struct timeval tv;
      int rx = 0;
      int tx = 0, sentBytes;
     UINT8* buf;
 
     assert( ( sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) >=  0 );      /* Create a reliable, stream socket using TCP */
 
     memset(&servAddr, 0, sizeof(servAddr));     /* Zero out structure */
     servAddr.sin_family      = AF_INET;             /* Internet address family */
     echoServAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );   /* Server IP address */
     servAddr.sin_port        = htons( ( unsigned short )OPR_PORT );
 
     tv.tv_sec = 1;
     tv.tv_usec = 0;
     if (setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,  sizeof tv))
         exit( -1 );
     if (setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv,  sizeof tv))
         exit( -1 );
 
     /* Establish the connection to the echo server */
     if ( connect( sock, ( struct sockaddr* )&servAddr, sizeof( servAddr ) ) < 0 ) {
         puts( "ERR: unable to connect 127.0.0.1" );
     }
 
     for ( ; ; ) {
         buf = ...;/* Obtain data which to be sent. */
 
 When I close the server when sending data, the following codes don't work and no any message is printed out!
         if ( ( ( sentBytes = send( sock, buf, MSG_SIZE, 0 ) ) == -1 || sentBytes != MSG_SIZE ) && (++tx < 1000) ) {
            printf("After timeout #%d, trying send again:\n", tx);
        }
 
 If I comment the source code about send() and only  enable recv(). 
Since no data is sent to server and the server doesn't  response anything, 
the following codes work and 'trying again ...'  message is printed out!
         while ( totalBytesRcvd < MSG_SIZE ) {   /* Receive feedback. */
             while (((bytesRcvd=recv(sock, buf, MSG_SIZE, 0)) == -1) && (++rx < 1000)) {
                 printf("After timeout #%d, trying recv again:\n", rx);
                 exit( -1 );
             }
             totalBytesRcvd += bytesRcvd;
         }
 
         free( buf );
     }
 
     close( sock );
 

That's a mighty big and complicated if-statement. I'd break it out not just for readability purposes, but also because C's operator precedence can be a little strange. It may be evaluating like (-1 || sentBytes) != MSG_SIZE or something silly like that.

Furthermore you should really be checking how much you've sent already and not resending bits you already have...

// outside loop
int sentTotal=0;

...

// inside loop
sentBytes=send(sock, buf+sentTotal, MSG_SIZE-sentTotal, 0);

// ==-1 is redundant, since -1 < MSG_SIZE
if(sentBytes < (MSG_SIZE-sentTotal))
{
        if(tx > 1000)
        {
                fprintf(stderr, "too many retries, giving up\n");
                break;
        }

        fprintf(stderr, "Timeout #%d, sent %d/%d\n",
                ++tx, sentBytes, MSG_SIZE-sentTotal);

        if(sentBytes > 0)
        {
                sentTotal+=sentBytes;
        }
}