Porting BSD Sockets to Winsock 3-Oct-2011 12:00 PM
Edit FancyEdit New New Blog Upload All Recent Home Logout
Table Of Contents

Unfortunately, I've had to port software that uses BSD sockets (ie OS X code) to Windows. My weapon of choice on Windows is the MinGW tools, so the build mechanism is the same on both sides, namely gmake.

Here are the bits that I always forget about to get things working:

Starting up the system

Some bits need ifdef wrappers based on the target system defined at build time. These are among the ones I use:


First, some necessary additions to the makefile, to include the winsock library. Be sure to add $(LIBS) to your linker line

ARCH := $(shell uname)

ifeq ($(ARCH),MINGW32_NT-5.1)
LIBS += -lwinsock32 -lmingw32


We also need to initialize the dll. I always forget about this one...

#if defined (__CYGWIN__) || defined(__MINGW32__)
#include <winsock2.h>

int main( int argc, char **argv )
#if defined (__CYGWIN__) || defined(__MINGW32__)
    WORD wVersionRequested;
    WSADATA wsaData;
    int ret;

/* other stuff */

#if defined (__CYGWIN__) || defined(__MINGW32__)
    wVersionRequested = MAKEWORD( 1, 1 );
    if( (ret = WSAStartup( wVersionRequested, &wsaData )) != 0 )
        fprintf( stderr, "Error: could not initialize winsock dll.n" );
        return -1;

Now, we can use the standard BSD socket calls elsewhere.

Using the calls

In the meat of the code, we need to do a few things to help make things actually work.


#if defined (__CYGWIN__) || defined (__MINGW32__)
#include <winsock2.h>

#ifdef __APPLE__  /* or whatever */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

additional macros

Some other changes need to be done, to fix some issues with read/write/close. They're handled by replacing your calls to read, write, close with netread, netwrite, net_close, and using the following macros.

#if defined(__unix__) || defined(VMS) || defined(__APPLE__)
#define net_read read
#define net_write write
#define net_close close
#elif defined(_WIN32)
#define net_read(x,y,z) recv(x,y,z,0)
#define net_write(x,y,z) send(x,y,z,0)
#define net_close closesocket

Notice that the define checks are different. no real reason for this. I have different ones in different places here to show that each could be used elsewhere.

System defines

Some notable system defines:

__CYGWIN__     /* Cygwin on Windows */
__MINGW32__    /* MinGW on Windows */
_WIN32         /* 32 bit Windows */
__APPLE__      /* OS X */
VMS            /* DEC VMS */
__unix__       /* misc Unix systems */