Here is what MSDN says: http://msdn.microsoft.com/en-us/library/ms737625%28VS.85%29.aspx
With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, *connect* will return SOCKET_ERROR, and * WSAGetLastError* will return WSAEWOULDBLOCK<http://msdn.microsoft.com/en-us/library/ms740668%28VS.85%29.aspx#winsock.wsaewouldblock_2>. In this case, there are three possible scenarios: - Use the *select*<http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx>function to determine the completion of the connection request by checking to see if the socket is writeable. And here is what man connect says on UNIX: *EINPROGRESS* The socket is non-blocking and the connection cannot be completed immediately. It is possible to select(2) <http://man-wiki.net/index.php/2:select> or poll(2) <http://man-wiki.net/index.php/2:poll> for completion by selecting the socket for writing. After select(2) <http://man-wiki.net/index.php/2:select> indicates writability, use getsockopt(2) <http://man-wiki.net/index.php/2:getsockopt> to read the *SO_ERROR* option at level *SOL_SOCKET* to determine whether *con-* *nect*() completed successfully (*SO_ERROR* is zero) or unsuccessfully (*SO_ERROR* is one of the usual error codes listed here, explaining the reason for the failure). So it seems that after select I need to check for writability, which is what I have been doing. Just as a test I started checking for read/write/error events by changing my code to this: fd_set myrset; FD_ZERO(&myrset); FD_SET(m_sock_fd, &myrset); fd_set mywset; FD_ZERO(&mywset); FD_SET(m_sock_fd, &mywset); fd_set myeset; FD_ZERO(&myeset); FD_SET(m_sock_fd, &myeset); status = select(m_sock_fd+1, &myrset, &mywset, &myeset, &tv); if (FD_ISSET(m_sock_fd,&myrset)) { cout << "read set" << endl << flush; } if (FD_ISSET(m_sock_fd,&mywset)) { cout << "write set" << endl << flush; } if (FD_ISSET(m_sock_fd,&myeset)) { cout << "error set" << endl << flush; } To my surprise, Windows puts the socket in the error set!!! which to my knowledge is not documented. Once select returns after signaling the error set, I call this: getsockopt(m_sock_fd, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) Now valopt is set to WSAECONNREFUSED. On the UNIX side, you are right, the connect returns EINPROGRESS, then the select signals the write set [ as documented ], the getsockopt then gives me ECONNREFUSED. I think this is a bug on Windows or at least the documentation is wrong. It should say to check on the error set not on the write set using the select call... Thanks. I have solved my problem. On Sun, Aug 23, 2009 at 6:20 PM, Ger Hobbelt <g...@hobbelt.com> wrote: > Probably the difference is due to timing; to get the connection > refused response, the client needs to at least transmit a packet and > either never see a response (timing out) or receive a RST or (in some > cases) an ICMP host-unreachable packet. Any way, the minimum time > required to give you the 'connection refused' response is two network > travels at the absolute minimum. Which means: it takes time. > > 'nonblocking' simply means 'I don't want to wait', so theoretically > the IP stack doesn't have to wait even a milli/micro/femtosecond > before returning to you. Which is what winsock does: queue request, > instant return, hence wouldblock. Apparently (and this can be due to a > myriad of reasons) your UNIX box either already 'knows' the server is > down or has an IP stack which waits a short while before returning > from connect, even in nonblocking conditions, so it is able to deliver > a 'connection refused' to you on the initial return. > > > It is true that by using a nonblocking connect I want an instant answer > but > > most importantly I want a correct answer. > > The answer is correct, because the answer is depending on time. > This may sound weird to you as it looks like the whole time/async > behaviour pattern here are what's troubling you, but the nonblocking > means the 'wouldblock' behaviour is the behaviour you would /expect/ > from the system; the fact that the other machine isn't doing this is, > at best, something to frown and ponder. /That/ one worries me, not the > Win box. > How can that machine know /instantaneously/ that the server at other > end of the wire is down? There's no paranormal vibe there, so... is > it's IP stack implemented to wait /anyway/ (bad!), despite the fact > that it knows it's got a nonblocking request from the application? Is > it at all /aware/ that this is a nonblocking handle/request here?! Or > more obscure and less probable: Is it caching icmp or other previous > responses regarding availability of other machines and shortcircuiting > the request due to that cached info? etc. (Or is the unix box the > server and client both, i.e. connection to localhost or eqv., so the > IP stack can short-circuit the request that way?) > > Your issue is, IMO, not the wouldblock, but the connrefused, which is > unexpected for a truely nonblocking socket. I checked my specs, and I > was correct in saying that you need to check for a READ event in > select() to get a notification about a completed nonblocking connect, > both on UNIX and WinSock. While you don't do that (you only ask > select() about WRITE events there) the select() will sit an pick it's > nose until timeout. > > Again, nonblocking is you telling the kernel 'go fetch, while I do > other stuff at the same time' and the /direct/ return of connrefused > only means one thing: the bastard is forcing you to wait anyhow until > the system/kernel is done doing its thing, which is /precisely/ what > you said, through NONblocking, you do NOT want (the waiting on the > call to finish). Either that or the unix box has obtained > precognition, which is a bit worrysome in its own way. > > > PS: are you addressing the server by IP number or domain name? In the > latter case, have you made sure the DNS request which converts the > FQDN to an IP produced a positive result? In other words: is connect > being fed a usable IP number and ditto port on both boxes? Are those > numbers identical on both boxes? Just making sure here as the > immediate connection refused is suspect. > > > > On Sun, Aug 23, 2009 at 5:35 PM, Md Lazreg<mdlaz...@gmail.com> wrote: > > Thank you Ger for your reply. > > > > > > It is true that by using a nonblocking connect I want an instant answer > but > > most importantly I want a correct answer. > > > > Using the same code under UNIX I get two instant correct answers: > > > > ECONNREFUSED [If my SSL server is down] > > EINPROGRESS [If my SSL server is up and listening] > > > > > > But under Windows I get the same answer regardless of the state of my SSL > > server: > > > > WSAEWOULDBLOCK > > > > My question is why _using the same code_ Windows is returning > WSAEWOULDBLOCK > > instead of WSAECONNREFUSED when my server is down? while UNIX correctly > > returns ECONNREFUSED... > > > > Thanks > > > > > > > > > > On Sun, Aug 23, 2009 at 5:04 PM, Ger Hobbelt <g...@hobbelt.com> wrote: > >> > >> Since you use a nonblocking connect, you're essentially telling the > >> software you want instant return. Which is what you get. > >> > >> Given that a TCP connection takes a little time (three network travels > >> at least), that's definitely more time than you wish to wait given > >> your nonblocking intent, so the IP stack properly and correctly tells > >> you it'll take some time before you get the final result --> > >> wouldblock. > >> > >> The next bit is where I'm a bit rusty (read as: the peculiarities of > >> WinSock have eroded in my brain), but a glance at the code shows > >> you're only select()ing for writing and IIRC a finalized non-blocking > >> connect is equivalent to a 'ready-for-READING' select signal - for > >> which you are not listening in your select as that argument is NULL. > >> Hence my advise to also pass your handle in a separate fdset to > >> select(read), i.e > >> > >> status = select(m_sock_fd+1, &myreadset, &mywriteset, > >> NULL, &tv); > >> > >> (so you can tell upon return which one fired) > >> > >> > >> and lastly there's the ever-there mind-you nitpick that nonblocking > >> I/O is well served with a statemachine around it, i.e. a loop, which > >> tracks the current state of your connections/activity and acts upon > >> that - it's the long way of saying that a connection may take longer > >> than 20 seconds to establish, so an if-chain and a long wait isn't the > >> end-all there, but this nitpick is not your problem. Yet. And the code > >> structure is not enough to prove there's no statemachine already there > >> in your code; the current code layout is a (very) weak hint, 's all. > >> > >> > >> Anyway, a tip: this is generic TCP/IP socket programming we're talking > >> about here and do yourself a favor and get a hold of the books by W > >> Richard Stevens (R.I.P.). It's what I grew up with and those books of > >> his have been among the very few which have never let me down in the > >> hour of need. They're still 100% applicable and for IPv6 specifics, > >> there's little enough change that the internet and manpages suffice > >> for that. They are not WinSock specific, but for that one's > >> peculiarities (such as the WSASelect limits) there's MSDN. > >> > >> Take care, > >> > >> Ger > >> > > > > > > > > -- > Met vriendelijke groeten / Best regards, > > Ger Hobbelt > > -------------------------------------------------- > web: http://www.hobbelt.com/ > http://www.hebbut.net/ > mail: g...@hobbelt.com > mobile: +31-6-11 120 978 > -------------------------------------------------- > ______________________________________________________________________ > OpenSSL Project http://www.openssl.org > User Support Mailing List openssl-users@openssl.org > Automated List Manager majord...@openssl.org >