[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