To understand this, you have to realize that Winsock is a derivative of the old BSD sockets API for Windows, and that it was created in the early 90s, back when the Windows 3.x dinosaur roamed the earth.
The Winsock API mirrors most of the BSD sockets API: where both provide a given function, both do the same thing. So, socket()
is the same call under both APIs. There are minor differences in places, but nothing bigger than the sort of differences you find between other POSIX systems...BSDs, commercial Unixes, Linux, OS X...
The Winsock API also provides many extensions relative to BSD sockets. Many have similar names as the original functions, but with a WSA prefix and camel-case for everything else. These functions are pure extensions to the original functions, not replacements for them. You pick which one to use depending on whether you need the extended functionality and whether your program has to be portable to systems that provide only the BSD sockets API. For instance, WSASocket()
takes the same parameters as socket()
plus three additional ones which have to do with Winsock extensions.
In addition, there are many Winsock extensions to the BSD sockets API that have no direct BSD equivalent, like WSAAsyncSelect()
. These generally have to do with differences in the way Windows programs are written, as compared to programs for Unixy systems. In this particular case, WSAAsyncSelect()
exists to make it easier to write single-threaded GUI programs that use sockets without network I/O blocking the GUI or vice versa. This is useful today, but absolutely critical to Winsock's success back in the Windows 3.1 days, which didn't have threads or other useful multiprocessing and IPC mechanisms.
There are a few oddballs like closesocket()
and ioctlsocket()
.
closesocket()
is the same as close()
under POSIX/Unix, except that it only takes sockets, not file handles. That's part of the reason for the name change, but the real reasons come from that early-90s history issue I brought up above. In those days, some Windows compilers -- there were more available then than today -- included POSIX API equivalents to ease porting code from other platforms to Windows. Such features were very limited, and didn't include sockets support, but nevertheless, the close()
function name was considered "taken" on Windows at that time. It isn't true any more, but Winsock is a product of its history and can't be changed now.
The story for ioctlsocket()
vs. ioctl()
is similar. One big difference is that ioctlsocket()
is greatly limited on Windows as compared to what ioctl()
can do on a Unix system. It exists only to provide a few network-related things that the original Winsock creators thought useful in the BSD sockets API. Over the years, much of what you can do with sockets and ioctl()
on Unixy systems but not with ioctlsocket()
has been added to Windows through other APIs, just one of which is WSAIoctl()
.
I've written an article on "The History of Winsock" for the Winsock Programmer's FAQ (which I maintain) that goes into more detail on all this. Another relevant article is "BSD Sockets Compatibility."