non blockingsockets on open

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

Thanks

Hello

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.

1 Like

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??

Hello
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));