fpagliughi / sockpp

Modern C++ socket library.
BSD 3-Clause "New" or "Revised" License
769 stars 126 forks source link

Setting read timeout fails (Bad file descriptor) #69

Closed MohamedSoliman19 closed 1 year ago

MohamedSoliman19 commented 1 year ago

I tried to set the read timeout using read_timeout function in stream_socket.h but it failed. I got "Bad file descriptor" error message. Is there a way to set the timeout or changing the default timout if that's possible ?

fpagliughi commented 1 year ago

I believe you need to connect or bind the socket first, then you can set the timeout.

MohamedSoliman19 commented 1 year ago

Actually, I would like to set the timeout of connect function itself, my app logic shouldn't wait for a long time to connect. I get the error message "Connection timeout" after 35-40 seconds which is too much for me and I need the waiting time for connection not to exceed 10 seconds at most. That's why I'm looking for a way to set the timeout to be around 10 seconds. I just found read_timeout and write_timeout in your library.

Could you tell me if it is possible to set the timeout for connect function ?

fpagliughi commented 1 year ago

This library is just a very thin wrapper around the operating system's socket library. Our connector classes literally just call the C connect() function to establish the connection.

My understanding is that the timeout depends on the Operating System (Windows? Linux? Mac? etc) and the type of socket you're trying to connect (TCP v4? v6? etc). But I believe that for most systems, it can only be changed on a per-host or maybe per-process basis - not for individual connections.

Do an internet search for the OS, socket type, and "connect timeout". That might get you the information you need.

For example, this is a nice little writeup for Linux: https://willbryant.net/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout

MohamedSoliman19 commented 1 year ago

I have used set_option function in the library to set tcp_syn_retries to lower number to speedup the connection timeout, and the function it returns 0 which means it succeeded. However, I still get the "connection timeout" error message after around 35 seconds.

int synRetries = 2; // Send a total of 3 SYN packets => Timeout ~7s conn_.set_option(IPPROTO_TCP, TCP_SYNCNT, &synRetries, sizeof(synRetries)); // conn_ is my defined sockpp::tcp_connector

this code is based on this answer: https://stackoverflow.com/questions/2597608/c-socket-connection-timeout#:~:text=The%20answers%20about%20using%20select()/poll()%20are%20right%20and%20code%20should%20be%20written%20this%20way%20to%20be%20portable.

Do you have any idea why it is not working ?

yycnet commented 1 year ago

1: set socket nonblocking 2: connect(...), it is non-blocking, return 3: ::select(...timeout...), check socket is writeable, if return timeout then shutdown 4: set socket blocking @fpagliughi

fpagliughi commented 1 year ago

Wow! Buried in PR #17, there's a commit (3dd60e649da41380e87d895feda5b02daf3ed53d) to add connect timeouts! I hadn't noticed that before. It's similar to what you describe.

I haven't had time to pull in that PR and add finish TLS support the way I want it implemented, but I knew there was some good stuff in there that I might want to cherry pick. Apologies that I hadn't spotted it before.

fpagliughi commented 1 year ago

I cherry-picked that commit from PR #17 (and a few others).

So now the connector class has a constructor and connect() method with a timeout. It was released in v0.8.1.

If this doesn't work for you, please re-open with some details.