Looping connect call for a non blocking socket


 
Thread Tools Search this Thread
Top Forums Programming Looping connect call for a non blocking socket
# 1  
Old 09-24-2012
Looping connect call for a non blocking socket

will there be any unexpected results on looping connect call for a non blocking socket to determine the connection based on error code. I am getting connection unsuccessful intermittently and so wondering whether is the timeout 500 millisec not sufficient or looping connect cause any unexpected.

//sample piece of code that I used


Code:
int type,x, MaxTries=0;
type = SOCK_STREAM;
x = fcntl(s,F_GETFL, 0);
fcntl(s,F_SETFL, x | O_NONBLOCK);
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
  while( (errno == EALREADY && MaxTries < 5) || (errno == EINPROGRESS && MaxTries < 5) )
                {
                        poll(NULL,0,100); //100 millisec sleep for 5 retries max.
                        connect(s, (struct sockaddr *)&sin, sizeof(sin));
                        MaxTries = MaxTries + 1;
                }
                if(errno == EISCONN)
                      printf("Connected");
                else
                      printf("Not Connected - %d",errno);
}


I know the Otherway is using SELECT. This would be better solution than looping but I doubt any significant difference in intermittent connections.

Code:
x = fcntl(s,F_GETFL, 0);
   fcntl(s,F_SETFL, x | O_NONBLOCK);

   FD_ZERO(&writeFDs);
   FD_SET(s, &writeFDs);

   timeout1.tv_sec = 0;
   timeout1.tv_usec = 500000;
   
   connect(s, (struct sockaddr *)&sin, sizeof(sin));
   if(select (maxFDs, (fd_set *)NULL, &writeFDs, (fd_set *)NULL, (struct timeval *)(&timeout1))  > 0 )   
        printf("Connected");
    else
       printf("Not Connected -%d", errno);

# 2  
Old 09-24-2012
Correct approach is after calling connect() to check if errno is set to EINPROGRESS and if so use select() to see when socket can be written to, also its best not to loop 5 times but set a single timeout since your select() will fire up when socket would change state (in relation to connect()) right away and you re just wasting CPU cycles. Keep in mind that kernel has internal timeout maximum set for TCP handshakes that is somewhere 1-2mins after that connect() should return ETIMEDOUT no matter what you do and only then you would need to have to implement a loop.

Edit:
If your connect() fails at first run then your problem is not in non-blocking sockets, but on receiving end or somewhere in between or maybe you set up 'struct sockaddr sin' incorrectly.

Last edited by expl; 09-24-2012 at 06:49 AM..
# 3  
Old 09-24-2012
I agree to use select but I want to correct that I don't loop 5 times wasting CPU cycle everytime. Worst case is 5 times. If the errno is EALREADY or EINPROGRESS I retry connect other wise I see for EISCONN.

I am believing this doesn't do anything with intermittent connections( Connection couldn't acquire in 500 milliseconds indicating errno - already inprogress) though is SELECT or looping connect. I am hoping 500 milli seconds not sufficient some times.

Do we have to keep the socket open till kernal level timeout occurs? We can also close the socket after custom timeout specified by using select?
# 4  
Old 09-24-2012
The code as written will not work as you expect if the initial connect() call fails with EALREADY or EINPROGRESS.

You need to reset errno to zero before each connect call.

Successful system calls will not change the value of errno.
# 5  
Old 09-24-2012
Thank You. I went for this looping logic because socket by default is writable. Rebooting the remote machine creating EPIPE and FD_ISSET(s, &writeFDs) returning success.

Do I have to do connect again to see the real state of the socket after FD_ISSET?

Code:
rc = select (maxFDs, (fd_set *)NULL, &writeFDs, (fd_set *)NULL, (struct timeval *)(&timeout1));

if(rc > 0 && FD_ISSET(s, &writeFDs))
{
    printf("Connection Success\n");
    write(s, "service", 7);
}

# 6  
Old 09-24-2012
Yes you have to connect again to bind socket to a remote port for further communication, in other words connect must return 0 once for the socket.
# 7  
Old 09-24-2012
So connect, select and again connect based on the return codes and errno indications achieve smooth non blocking connection but I am still thinking of looping connect call and I verified the truss to see the return code of connect when I loop -

First remote connect said - EINPROGRESS as expected.
Next try indicated - EISCONN. Indicating already connected.
Even if not then would have indicated EALREADY. Having 100 milli secods each time before trying to connect, there should not be any issue except that the last retry may indicate connect = 0 and will not update errno (The only chance of failure in the loop after 400 milli seconds, mostly in bad network cases). Other case If connect returned 0 will not update errno but the next try to same connected socket would indicate error - EISCONN, correct?

connect(4, 0x080453E0, 16, SOV_DEFAULT) Err#150 EINPROGRESS
pollsys(0x00000000, 0, 0x08045330, 0x00000000) = 0
connect(4, 0x080453E0, 16, SOV_DEFAULT) Err#133 EISCONN
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Cannot connect to socket

solaris client report "cannot to socket(code 25)" while trying to backup on veritas netbackup 6.5.5 server (1 Reply)
Discussion started by: EUGINIAM
1 Replies

2. Programming

Looping problems socket programming in C

Sorry if I posted 2 separate questions. I'm currently doing socket programming on my current task. As you can see below in the client side. I've tried to do a loop so I will be able to get prompt for input over and over again. This is the code. do{ printf("Please your name > ");... (10 Replies)
Discussion started by: aLHaNz
10 Replies

3. Programming

socket accept() keeps looping

I'm using C/ C++ with gcc on Linux. I've a server socket where accept() is called on the socket inside a while() loop. The problem I am facing is that the first call to accept is blocking (i.e., the program waits for the first connection) but as soon as I fork afterwards (so that the child process... (2 Replies)
Discussion started by: jaywalker
2 Replies

4. Programming

write on Non Blocking Socket

How to know whether socket is ready for write. select(maxfds, (fd_set *)NULL, &writefds, NULL, &timeout); By default socket is set for write without checking whether it would block or not? If so how do I know my FD is ready for writing. (3 Replies)
Discussion started by: satish@123
3 Replies

5. Programming

non blocking connect

OS : solaris 10 X86 I created stream socket, tries to connect to port 7 on the remote machine. After doing the non blocking connect call I did select with time out value is 3 secs. I am always getting timed out though I am writing prior to select. code: x=fcntl(S,F_GETFL,0);... (1 Reply)
Discussion started by: satish@123
1 Replies

6. Solaris

Non-blocking connect readability & writeability

Hello, When using a non-blocking connect, is it _guaranteed_ that connection completion can be detected by selecting for writeability? I have encountered situations where the socket has returned both readable and writeable at the same time - having trawled the net, I have seen some old posts... (1 Reply)
Discussion started by: tristan12
1 Replies

7. Programming

connect() socket API

Is there any relation between the connect() socket API and the TCP's Transmission Control Block. Also how does connect detect that a socket is in use i.e., EADDRINUSE (1 Reply)
Discussion started by: sunaina
1 Replies

8. UNIX for Advanced & Expert Users

connect problem for sctp socket (ipv6 socket) - Runtime fail Invalid Arguments

Hi, I was porting ipv4 application to ipv6; i was done with TCP transports. Now i am facing problem with SCTp transport at runtime. To test SCTP transport I am using following server and client socket programs. Server program runs fine, but client program fails giving Invalid Arguments for... (0 Replies)
Discussion started by: chandrutiptur
0 Replies

9. Shell Programming and Scripting

Looping connect to different server

Hi there. I am attempting to write a script that will read through a flat file, get the server and directory that I want the size for, connect to the server, get the directory size, and send it to an output file. Here is what I have: while read LINE do NAME=`echo $LINE | awk -F'~' '{print... (5 Replies)
Discussion started by: la_womn
5 Replies

10. UNIX for Dummies Questions & Answers

Blocking ftp users to connect using telnet

Hi everybody ! We have all flavors of Unix / Linux and we want to restrict ftp users to telnet our servers. We can't disable telnet because we have other users using it. :confused: Are there any thing that could be done to solve this thing ??? Best regards, Julio Moreira (11 Replies)
Discussion started by: juliocdrm
11 Replies
Login or Register to Ask a Question