Home/Support/Support Forum/non blockingsockets on open
New and improved user forum site coming soon
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

non blockingsockets on open

0 votes
I have an appication that needs to open a tcp socket

the problem is that if the address provided is not reachable
the open function wait for too long before returning the error code.

to speed up the process I usually set the the socket to be non blocking and use select with a timeout.

But it seems to be malfunctioning and the socket still wait an eternity to return with the error
int tcp_socket = 0; tcp_socket = socket(AF_INET, SOCK_STREAM, 0); // set socket non-blocking fcntl(tcp_socket, F_SETFL, fcntl(tcp_socket, F_GETFL, 0) | O_NONBLOCK); // Initialize the file descriptor set FD_ZERO(&fds); // Add socket to set FD_SET(tcp_socket, &fds); // Connect connect(................); // Initialize the connection timeout structure connectionTimeout.tv_sec = 0; connectionTimeout.tv_usec = 200000; // select blocks forever until data ready. // select returns 0 if timeout, > 1 if input available, -1 if error. n = select(tcp_socket+1, NULL, &fds, NULL, &connectionTimeout); if(n < 0){ //ERROR }else if(n == 0){ //TIMEOUT }

Some idea on how I can get the desired behavior

asked Jan 26, 2015 in NET+OS by gavello New to the Community (16 points)

Please log in or register to answer this question.

1 Answer

+1 vote

I am a little confused by your application code. I believe you want a select before the connect and another select after the connect but before the recv. That way if the guy you want to connect to is not available your select before the connect will timeout and you can go off and do something else and try again later. Similarly if the connect succeeds but the recv times out, the second select will catch that and allow you to wait until something comes in from the peer.

Be careful that on recv that you check for recv 0 bytes meaning that the peer disconnected. I have seen people forget to check for that and get into a nasty loop.
answered Jan 26, 2015 by dakotas_dad Veteran of the Digi Community (694 points)
that what I'm doing but I found problems setting O_NONBLOCK flag fcntl return alwais -1
int flags = fcntl(tcp_socket,F_GETFL,0); fcntl(tcp_socket, F_SETFL, flags | O_NONBLOCK);

maybe I should use
?? block_option = ??; setsockopt(tcp_socket, SOL_SOCKET, SO_NONBLOCK, (char*)&block_option, sizeof(block_option));

but I'm not sure how to use the function since I do not know what type and value to assign

any idea??
   Yes I have an idea.

int block_option = 1; // 1 = on and 0 = off.
then in the call pass a pointer to block_option and typecast to a char *.

So your code replicated below is correct, just, as I stated above, define as an int, typecast to char * and pass pointer to block_option.
setsockopt(tcp_socket, SOL_SOCKET, SO_NONBLOCK, (char*)&block_option,  sizeof(block_option));