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:


TOP

1. 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:

TOP

1.1. GNUMakefile

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
endif
TOP

1.2. main.c

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

#if defined (__CYGWIN__) 

 defined(__MINGW32__)
#include <winsock2.h>
#endif

int main( int argc, char **argv )
{
#if defined (__CYGWIN__) 

 defined(__MINGW32__)
    WORD wVersionRequested;
    WSADATA wsaData;
    int ret;
#endif

/* 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;
    }
#endif

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


TOP

2. Using the calls

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

TOP

2.1. Includes

#if defined (__CYGWIN__) 

 defined (__MINGW32__)
#include <winsock2.h>
#endif

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

2.2. 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
#endif

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.


TOP

3. 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 */