0% found this document useful (0 votes)
13 views

Differences between socket programming on Windows, Linux, and macOS

This document outlines the key differences in socket programming across Windows, Linux, and macOS, focusing on the use of Winsock and Berkeley sockets. It covers necessary headers, linking requirements, initialization, socket creation and closure, configuration, error handling, and other notable distinctions. The author emphasizes the importance of writing portable networking code and suggests using common functions to ensure compatibility across platforms.

Uploaded by

iamashokaryal
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

Differences between socket programming on Windows, Linux, and macOS

This document outlines the key differences in socket programming across Windows, Linux, and macOS, focusing on the use of Winsock and Berkeley sockets. It covers necessary headers, linking requirements, initialization, socket creation and closure, configuration, error handling, and other notable distinctions. The author emphasizes the importance of writing portable networking code and suggests using common functions to ensure compatibility across platforms.

Uploaded by

iamashokaryal
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

6/20/23, 7:11 AM Differences between socket programming on Windows, Linux, and macOS

HANDS-ON NETWORK PROGRAMMING WITH C


Written By Lewis Van Winkle

DIFFERENCES BETWEEN SOCKET


PROGRAMMING ON WINDOWS, LINUX, AND
MACOS

This site, and my book, both focus on writing portable networking


code. Of course, it's not possible to write portable code until you
know the differences between platforms.
This article aims to provide a quick run-down of the major
differences between network programming on Windows using
Winsock and network programming on Linux or macOS using BSD
sockets / Berkeley sockets.

THE NEEDED HEADERS


The needed header files for Winsock (Windows) and Berkeley
sockets (Linux and macOS) differ.
On Windows, you may want to include your headers like this:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <winsock2.h>
#include <ws2tcpip.h>

To use Berkeley sockets on Linux or macOS you will probably want


the following headers:
#include <sys/types.h>
#include <sys/socket.h>
https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/ 1/5
6/20/23, 7:11 AM 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")

Other compliers will need you to pass in a command line parameter


to link the library.
This isn't needed on Linux or macOS.

WINSOCK NEEDS TO BE INITIALIZED


Before you can use Winsock on Windows, you need to initialize it.
This is done with a call to the WSAStartup() function. An example
follows:
WSADATA d;
if (WSAStartup(MAKEWORD(2, 2), &d)) {
fprintf(stderr, "Failed to initialize.\n");
}

The MAKEWORD() macro is used to request the version of Winsock


— 2.2 in this case. The WSADATA returned by WSAStartup()
indicates the actual version of Winsock returned. It's worth noting
that the Winsock API has been stable for a very long time. Winsock
version 2.2 was first released in 1996, and at the time of this writing
(2020), it's still the latest version.
You will also want to call the WSACleanup() function when your
Windows program is finished using Winsock.
On Linux and macOS, there is no need to call any initialization
functions or cleanup functions when using the Berkeley socket
https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/ 2/5
6/20/23, 7:11 AM Differences between socket programming on Windows, Linux, and macOS

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.

The way you check if your call to socket() succeeded or failed


varies between platforms.
I've written an article about the return value of socket(). You'll
want to check that out to learn how to determine if the call to
socket() succeeded or failed.

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.

Both platforms implement the setsockopt() function. However,


the type of the optval parameter of that function on Windows is
const char*, while on other platforms it is const void*. This is a
tiny difference, and it won't affect most C programmers. If you're
writing code to be complied as C++, you may need an explicit cast
before calling setsockopt().
https://handsonnetworkprogramming.com/articles/differences-windows-winsock-linux-unix-bsd-sockets-compatibility/ 3/5
6/20/23, 7:11 AM Differences between socket programming on Windows, Linux, and macOS

ERROR CODES AND MESSAGES


On Linux and macOS, you can get the last socket error by simplying
reading the errno global variable. On Windows you'll want to use
the WSAGetLastError() function.
Once you have the error code, you may also want a more
descriptive error message. On Linux and macOS, you can use the
strerror() function for this, while on Windows you will want to
use the FormatMessage() function.
You can read about a cross-platform approach to socket error
messages here.

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

You might also like