Socket “Not ready for writing” when trying to Connect?

Question:

Can you tell from this log why it would say “socket is not ready for writing”?

  OpenSmtpConnection:
     DllDate: Jun  9 2009
     UnlockPrefix: ****
     Username: Administrator
     Component: ActiveX
     Need new SMTP connection
     SMTP_Connect:
       Connecting to SMTP server mail.****.com:25
       smtp_host: mail.****.com
       smtp_port: 25
       domain: mail.****.com
       smtp_user: ****
       socket is not ready for writing
       Connect function failed.
       SocketError: WSAEWOULDBLOCK The socket would block.
       For more information see http://www.chilkatsoft.com/p/p_172.asp
       Failed to connect to SMTP server.
     Failed to connect to SMTP server

Answer:

All programs running on Windows, Linux, Unix, etc. that communicate using TCP/IP sockets ultimately use (directly or indirectly) the socket system calls (WinSock for Windows, but the functions are virtually the same). These include the following system-level functions: bind, listen, accept, connect, recv, send, select, etc. (see Guide to Network Programming) Even if your coding in Java or .NET, internal to the Java Runtime or the .NET Framework, it is these same socket-level functions that are ultimately called to carry out the work of connecting, reading, and writing TCP/IP sockets. It’s been that way for 30 years…

Naturally, the Chilkat libs call the WinSock functions to implement all of the TCP/IP based protocols — SMTP, IMAP, POP3, FTP, HTTP, SSH, etc. Internally, Chilkat uses non-blocking sockets — meaning that we never want to “hang” the calling thread. This is accomplished internally by using the “select” system call. Chilkat never reads, writes, connects, or tries to accept a connection without first knowing that the socket has data waiting, or that the socket function call will complete without delay. If you examine the description of the “select” WinSock function, you’ll see that there are arguments for both read and write file descriptors. Here’s an excerpt:

...
"The parameter writefds identifies the sockets that are to be checked for writability. If a socket is 
processing a connect call (nonblocking), a socket is writeable if the connection establishment 
successfully completes. If the socket is not processing a connect call, writability means a send, 
sendto, or WSASendto are guaranteed to succeed."
...

The amount of time your application is willing to wait for the Connect to complete is controlled by
setting the Chilkat ConnectTimeout property. If no connection is possible in this amount of time,
(internally) the “select” function times out — i.e. the socket is not “writeable”. We get the
WSAEWOULDBLOCK error because technically, if we called the socket “connect” system call — it
would block (i.e. your program would hang).

A failure to connect is caused by one of the following:
1) There is no server listening at the remote hostname:port.
2) A firewall at either the client or server side is blocking the connection.
3) Something else is blocking the connection — perhaps TCP/IP port filtering or anti-virus.
4) The server is too slow to respond — perhaps your ConnectTimeout is too short and the server is far too busy…

Socket Error: WSAEWOULDBLOCK

NOTE: If this error occurred while trying to establish an FTP data connection, also see this: http://cknotes.com/?p=282

A WSAEWOULDBLOCK error when trying to establish a TCP/IP socket connection indicates one of the following conditions:

  1. A firewall at either the client or server side is blocking the connection.
  2. There is no server listening at the remote host:port to accept the connection
  3. Some other software, such as an anti-virus or anti-spyware program is blocking the connection.
  4. The server was too slow in accepting the connection.  Increase the value of the ConnectTimeout property.

You may open a DOS prompt and try to telnet to the remote host:port to test connectivity. This page provides more information: WSAEWOULDBLOCK

Note: It is impossible for the client to distinguish between any of the cases described above.  It’s similar to if you were knocking on a door and nobody answers — you have no information — you don’t know if the person simply chose not to answer the door, if the person is not home, or if the person simply cannot hear the knocking.  In all cases, the client’s knowledge is the same: there is no response and you have to decide how long you’re willing to wait…