lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Can one find out how much data can be sent (lwip_write)


From: Peter
Subject: Re: [lwip-users] Can one find out how much data can be sent (lwip_write) to a NON blocking socket without loss of data?
Date: Thu, 22 Dec 2022 12:05:43 +0000

Thank you for your reply.

I don't understand how FD_ISSET can be used to work out when one can
write to the socket.

However, I have implemented the short socket write:

            //read rx_len bytes from the buffer and send over ethernet
            rx_len = serial_receive(i, buf, rx_len);
            if (rx_len > 0)
            {
              int tmp_len;
              bool fail = false;
              // This returns # bytes actually written (if a positive
value)
              tmp_len = write(ethser_port[i].client_fd, buf, rx_len);
              if (tmp_len<0) fail=true;

              // Process the case where not all rx_len bytes were
written (by the NON blocking socket)
              // This can cause a wait here if the other end is slow
in consuming the data.
              if ( (tmp_len<rx_len) && !fail )
              {
                  int offset = 0;
                  do
                  {
                          rx_len -= tmp_len;
                          offset += tmp_len;
                          tmp_len = write(ethser_port[i].client_fd,
&buf[offset], rx_len);
                          if (tmp_len<0) fail=true;
                  }
                  while ( ( tmp_len>0 ) && !fail );
              }

              if ( fail )
              {
                 //something went wrong. Close the client socket
                 close(ethser_port[i].client_fd);
                 ethser_port[i].client_fd = -1;
                 continue;  //break from the for-loop early
              }

              ethser_port[i].rx_count += rx_len;

            }

If I understand it right, the socket write returns # of bytes actually
written, or various negative values for error conditions. Or it could
return zero if you asked it to write zero bytes, I assume.

I am always writing from a 512 byte buffer (containing 1-512 bytes) so
if the write returns say 256, then I need to repeat the write with a
length of 256 and with the start of the data being &buffer[256].


>Hello Peter,
>
>On 2022-12-22 00:20, Peter wrote:
>> Unfortunately the socket is non-blocking so if the data is
>> arriving too fast, some gets lost.
>
>This is the most common mistake made with TCP socket programming:
>
>Not handling short writes properly.
>
>You also get this with blocking sockets, those also don't guarantee
>to send all supplied data. In practice, you always get a short write
>before the socket would block.
>
>If you don't want short writes, use the RAW API.
>
>> The obvious solution (make the socket blocking) would cause
>> problems elsewhere.
>> 
>> Is there some way to get how many bytes a write socket can accept?
>
>Check and handle the send return value correctly.
>
>> Doing some digging around, I have found stuff like this
>> 
>> //socket ready for writing
>>         if(FD_ISSET(new_sd, &write_flags)) {
>>             //printf("\nSocket ready for write");
>>             FD_CLR(new_sd, &write_flags);
>>             send(new_sd, out, 255, 0);
>>             memset(&out, 0, 255);
>>         }   //end if
>> 
>> but it doesn't seem to be suitable.
>
>This solves your real problem: Knowing when to send more data.
>
>(Assuming your send rate is not consistently too high for the
>receiver to keep up, and your code does sends in bursts.)
>
>> 
>> Is there some way to get a buffer_space() function, so I can
>> extract only that many bytes (max) out of the UART buffer?
>
>send() returns how many bytes are sent, you just have to keep the
>remainder and send that when the socket can accept more (see above).
>
>Greetings,
>
>Indan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]