Wednesday, December 29, 2010

The Differences Between Network Calls in Windows and Linux

Berkeley and Microsoft socket models that are mostly compatible on the source code level are not so cross-platform in practice.
Let’s examine some subtle differences in their implementation. These differences were found when writing a cross-platform RPC for redirection of network calls of some process from one OS to another.

Socket Types
BSD:    int
Win:    void * // macros SOCKET

While the processor capacity is 32 bits, there are no problems in mutual displaying. On Windows 64 bits, the SOCKET type is twice larger in size.
The socket descriptor on BSD does not differ from the file descriptor. It means that some system calls accept descriptors of sockets and files simultaneously (for example, such commonly used calls as close(), fcntl(), and ioctl()).

There is one more side effect that appears in some cases. The matter is that systems, which support Berkeley model, have a small numerical value of the socket descriptor (less than 100) and the descriptors that are created in succession differ on 1. In the Microsoft model, such descriptors have values that are approximately more than 200 at once, and the descriptors created in succession differ on sizeof(SOCKET).

Error Handling
BSD:   Calls return -1, global variable errno is set.
Win:    Calls return -1 (SOCKET_ERROR macro), we receive the status with WSAGetLastError().
errno constants and Windows error codes have absolutely different values.
Socket creation
 socket(int af, int type, int protocol);
Constants for the first argument have absolutely different values on BSD and Windows. Constants for the second argument coincide so far.

Socket Setting
BSD:
 getsockopt(int sockfd, int level, int option_name, void *option_value, socklen_t *option_len);
 setsockopt(int sockfd, int level, int option_name, void const *option_value, socklen_t option_len);
Win:
 getsockopt(SOCKET sock, int level, int option_name, void *option_value,  socklen_t *option_len);
 setsockopt(SOCKET sock, int level, int option_name, void const *option_value,  socklen_t option_len)

Flag constants for the second and third arguments have absolutely different values on BSD and Windows.

Read more: Codeproject