Differences between socket programming on Windows, Linux, and macOS
Differences between socket programming on Windows, Linux, and macOS
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
LINKING
On Windows, you will need to link your networked programs with
the ws2_32 Winsock library. Some compliers may let you do this
with a pragma:
#pragma comment(lib, "ws2_32.lib")
libraries.
CREATING A SOCKET
When creating a new socket, you'll need to call the socket()
function. On Windows, this function returns an unsigned int,
while on Linux and macOS socket() returns a normal (signed)
int.
CLOSING A SOCKET
Closing a socket on Windows/Winsock uses the closesocket()
function.
Closing a socket on Linux or macOS uses the close() function.
This is because on Unix-like systems socket handles are essentially
equivalent to file handles. This means that on Linux and macOS,
you can generally use all of the general purpose file functions with
socket handles (e.g. read(), write()). On Windows, socket
handles can only be used with special socket functions.
CONFIGURING A SOCKET
On Windows you can set some socket features with the
ioctlsocket() function. On Unix-like systems, you can use the
fcntl() (or the older and not recommended ioctl()) function.
OTHER ISSUES
There are many other differences as well. For example, the
select() function used to multiplex sockets works very similar on
both Windows and Unix-like systems, but the way this function
stores socket identifiers is different between platforms. So you can
and should use select() on both platforms, but you have to be
careful about how you interact with it. The same is true of many
other socket functions as well.
For more information on the differences between Winsock and
Berkeley sockets, there is a really good write-up from Microsoft
about porting socket applications to Windows.
For new programs, I suggest you take a nuanced approach and
attempt to write code that works on both platforms, whenever
possible. For example, on Linux you could use write() to send
data through a socket. However, if you use the send() function
instead, it will work on both Linux and Windows. Instead of working
to port code between systems, it's easier to simply use portable
methods from the beginning. That's a lot of what I try to address in
my book.
https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/ 4/5