Advertisement

Looking to Port From Windows To Linux/Unix

Started by May 24, 2004 06:52 AM
6 comments, last by Pyros-AtEarth 20 years, 8 months ago
Hey there, I am currently writing servers for my MMORPG, and i am wondering how exactly i can port my windows server to unix. It uses winsock (doh!) and so there is the sockets equivilent. In windows you have to use WSAdata, but what do you use in unix? Regards Pyros [edited by - Pyros-Atearth on May 24, 2004 7:55:42 AM]
I just did a quick search for WSAdata, so what I say is a quick shot:

It seems to me that the WSAdata structure is just necessary to determine the version of the winsock implementation (to implement different code paths for different specs?). This should be unnecessary on most if not all Un*x platforms since those use BSD/POSIX sockets which didn''t change for a long time. There are some platform-specific capabilities though, but those are normally identified in the manpages. If you keep to the standard, there should be no problems. AFAIK, there''s no equivalent to the WSAStartup call.
Advertisement
Look up HawkNL for a generic cross platform wrapper around sockets.

http://www.hawksoft.com I think.
yes, WSAData is only needed for WSAStartup to initialised winsock ie. you don't need it on unix.

Here are two header files which contain the platform specific parts of my socket-wrapper.
platform.h:
#ifndef MINISOCK_PLATFORM#define MINISOCK_PLATFORM#ifdef _WIN32	#define WIN32_LEAN_AND_MEAN	#include <winsock.h>	#include <stdio.h>	#define MINISOCK_SEND_SIGNAL_FLAGS 0	#define MINISOCK_LAST_ERROR WSAGetLastError()#else //linux	#include <stdio.h>	#include <errno.h>	#include <unistd.h>	#include <sys/types.h>	#include <sys/socket.h>	#include <netinet/in.h>	#include <fcntl.h>	#include <netdb.h>	#include <arpa/inet.h>	#include <string.h>	#include <time.h>	#ifndef closesocket	#define closesocket close	#endif	#ifndef SOCKET	#define SOCKET int	#endif	#ifndef SOCKET_ERROR	#define SOCKET_ERROR -1	#endif	#define MINISOCK_SEND_SIGNAL_FLAGS MSG_NOSIGNAL	#define MINISOCK_LAST_ERROR errno#endif //def _WIN32#include "errors.h"#endif //ndef MINISOCK_PLATFORM 


and errors.h:
#ifndef MINISOCK_ERRORS#define MINISOCK_ERRORS#ifdef _WIN32	#define MINISOCK_ADDRINUSE		WSAEADDRINUSE	#define MINISOCK_WOULDBLOCK		WSAEWOULDBLOCK	#define MINISOCK_ALREADY		WSAEALREADY	#define MINISOCK_ISCONN			WSAEISCONN	#define MINISOCK_INVAL			WSAEINVAL	#define MINISOCK_INPROGRESS		WSAEINPROGRESS	#define MINISOCK_CONNRESET		WSAECONNRESET	#define MINISOCK_ADDRNOTAVAIL	WSAEADDRNOTAVAIL	#define MINISOCK_AFNOSUPPORT	WSAEAFNOSUPPORT	#define MINISOCK_CONNABORTED	WSAECONNABORTED	#define MINISOCK_CONNREFUSED	WSAECONNREFUSED	#define MINISOCK_DESTADDRREQ	WSAEDESTADDRREQ	#define MINISOCK_FAULT			WSAEFAULT	#define MINISOCK_HOSTDOWN		WSAEHOSTDOWN	#define MINISOCK_HOSTUNREACH	WSAEHOSTUNREACH	#define MINISOCK_MFILE			WSAEMFILE	#define MINISOCK_MSGSIZE		WSAEMSGSIZE	#define MINISOCK_NETDOWN		WSAENETDOWN	#define MINISOCK_NETRESET		WSAENETRESET	#define MINISOCK_NETUNREACH		WSAENETUNREACH	#define MINISOCK_NOBUFS			WSAENOBUFS	#define MINISOCK_NOTCONN		WSAENOTCONN	#define MINISOCK_NOTSOCK		WSAENOTSOCK	#define MINISOCK_PFNOSUPPORT	WSAEPFNOSUPPORT	#define MINISOCK_SHUTDOWN		WSAESHUTDOWN	#define MINISOCK_TIMEDOUT		WSAETIMEDOUT	#define MINISOCK_HOST_NOT_FOUND	WSAHOST_NOT_FOUND	#define MINISOCK_NO_RECOVERY	WSANO_RECOVERY	#define MINISOCK_TRY_AGAIN		WSATRY_AGAIN	//Winsock specific	#define MINISOCK_PROCLIM			WSAEPROCLIM	#define MINISOCK_NOTINITIALISED		WSANOTINITIALISED	#define MINISOCK_SYSNOTREADY		WSASYSNOTREADY	#define MINISOCK_VERNOTSUPPORTED	WSAVERNOTSUPPORTED#else	#define MINISOCK_WOULDBLOCK		EAGAIN	#define MINISOCK_ALREADY		EALREADY	#define MINISOCK_ISCONN			EISCONN	#define MINISOCK_INVAL			EINVAL	#define MINISOCK_INPROGRESS		EINPROGRESS	#define MINISOCK_CONNRESET		ECONNRESET	#define MINISOCK_ADDRINUSE		EADDRINUSE	#define MINISOCK_ADDRNOTAVAIL	EADDRNOTAVAIL	#define MINISOCK_AFNOSUPPORT	EAFNOSUPPORT	#define MINISOCK_CONNABORTED	ECONNABORTED	#define MINISOCK_CONNREFUSED	ECONNREFUSED	#define MINISOCK_DESTADDRREQ	EDESTADDRREQ	#define MINISOCK_FAULT			EFAULT	#define MINISOCK_HOSTDOWN		EHOSTDOWN	#define MINISOCK_HOSTUNREACH	EHOSTUNREACH	#define MINISOCK_MFILE			EMFILE	#define MINISOCK_MSGSIZE		EMSGSIZE	#define MINISOCK_NETDOWN		ENETDOWN	#define MINISOCK_NETRESET		ENETRESET	#define MINISOCK_NETUNREACH		ENETUNREACH	#define MINISOCK_NOBUFS			ENOBUFS	#define MINISOCK_NOTCONN		ENOTCONN	#define MINISOCK_NOTSOCK		ENOTSOCK	#define MINISOCK_PFNOSUPPORT	EPFNOSUPPORT	#define MINISOCK_SHUTDOWN		ESHUTDOWN	#define MINISOCK_TIMEDOUT		ETIMEDOUT	#define MINISOCK_HOST_NOT_FOUND	HOST_NOT_FOUND	#define MINISOCK_NO_RECOVERY	NO_RECOVERY	#define MINISOCK_TRY_AGAIN		TRY_AGAIN#endif#endif //ndef MINISOCK_ERRORS 

As you can see my wrapper goes by the funky name minisock, that is irrelevant for you but hopefully seeing this little bit of source helps... have fun.

[edited by - zppz on May 24, 2004 8:50:05 AM]
Making straight socket code work the same on Windows and Unix is pretty trivial. Just avoid anything that begins with WSA other than WSAStartup/WSACleanup which you can #define into non-existance on the Unix side. The only other gotcha is that on the Windows side you need to call closesocket instead of close but again this is just another trivial #define.

-Mike
If you sticked to berkley sockets you should be fine for 95% of the times.
Thingies that are different:

Implementation of FD_SET. If you did not use the standard macro''s for the FD_SET you need to recode those parts. Windows uses an integer array to store the FD ID''s. Unix uses a 64 bit long and sets/unsets bits of that long. It is advisable to stick to the macros as those are available on both platforms.

WSAStartup and WSAShutdown don''t exist. A "#ifdef WIN32" is the quickest fix.

getHostByName does not exist under Unix. The function is called differently, but it takes the same structure.
#ifdef UNIX
#define getHostByName resolvhostbyname // don''t know if that the corect function name, but its in the resolv library somewhere

You need to typedef SOCK_ADDR (or was it SOCK_ADDR_IN?) yourself.

Starting threads is different. You need to figure those out yourself since I don''t have any source at hand here. A #define works best:

#ifdef WIN32
#define FUNCTIONPTR int
#define FUNCTIONPARAM void* // make thread function as FUNCTIONPTR threadFunction(FUNCTIONPARAM parameter) { }
#define startThread(x,y) //etc etc
#endif

#ifdef UNIX
#define FUNCTIONPTR void
#define FUNCTIONPARAM void*
#define startThread(x,y) // etc etc
#endif


I think that''s all that is different...
There are a few quirks in Unix that I''m not sure happen in every Unix version. One of those is the select() function not falling through when you clsoe the socket that is listening. You need to make a dummy connection for it to fall through so you can make the thread exit nice and clean.

STOP THE PLANET!! I WANT TO GET OFF!!
Advertisement
quote:
Original post by Structural
getHostByName does not exist under Unix. The function is called differently, but it takes the same structure.

(...)

You need to typedef SOCK_ADDR (or was it SOCK_ADDR_IN?) yourself.



The BSD variant is gethostbyname( const char* name ), the type sockaddr_in should be defined in sys/types.h or netinet/in.h. All methods that require it take a generic sockaddr* as parameter due to the many possible types of sockets.

This should help.
Hey,

I have a new problem, i use a mysql api on my server, and it requires 3 DLLs, libeay32.dll, libmysql.dll and ssleay32.dll

I got these dll''s and the server works fine in windows.

Therefore i will need to use the unix mysql api, which needs a total recode of the server, therefore i will be making 2 sets of source code, as the main gut of the servers will be the same, with minor differences.

Thanks for your help!

Pyros

This topic is closed to new replies.

Advertisement