GoB*_*sto 67
WinSock和POSIX套接字以类似的方式工作 - 主要是因为Windows套接字最初基于BSD的代码:
虽然这些专有的BSD衍生产品在很大程度上被20世纪90年代的UNIX System V Release 4和OSF/1系统所取代(两者都包含了BSD代码并且是其他现代Unix系统的基础),后来的BSD版本为几个开放提供了基础.源开发项目,如FreeBSD,OpenBSD,NetBSD,Darwin或PC-BSD,正在进行中.反过来,它们全部或部分地包含在现代专有操作系统中,例如Microsoft Windows中的TCP/IP(仅限IPv4)网络代码以及Apple OS X和iOS的大部分基础.
但是,如果您想编写"socket-library-agnostic"代码,则需要处理一些不同的事情.
注意:以下示例已在Windows XP(x86)和Debian Testing(AMD64)上使用Code :: Blocks和GCC进行了测试.
您需要包含不同的头文件,具体取决于您是否使用Windows:
#ifdef _WIN32
/* See http://stackoverflow.com/questions/12765743/getaddrinfo-on-win32 */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 /* Windows XP. */
#endif
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
/* Assume that any non-Windows platform uses POSIX-style sockets instead. */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h> /* Needed for getaddrinfo() and freeaddrinfo() */
#include <unistd.h> /* Needed for close() */
#endif
Run Code Online (Sandbox Code Playgroud)
您还需要Ws2_32
在Windows上链接lib文件.
下面的函数说明了如何初始化WinSock v1.1并在之后进行清理:
int sockInit(void)
{
#ifdef _WIN32
WSADATA wsa_data;
return WSAStartup(MAKEWORD(1,1), &wsa_data);
#else
return 0;
#endif
}
int sockQuit(void)
{
#ifdef _WIN32
return WSACleanup();
#else
return 0;
#endif
}
Run Code Online (Sandbox Code Playgroud)
对于POSIX样式的套接字,您只需使用int
存储套接字句柄即可.无效的套接字由负值表示.
但是,WinSock套接字是UNSIGNED整数,使用特殊的constant(INVALID_SOCKET
)而不是负数.
您可以typedef
通过SOCKET int
在POSIX上抽象差异,并在宏或函数后面隐藏"有效套接字"检查.
以下功能说明了不同之处:
/* Note: For POSIX, typedef SOCKET as an int. */
int sockClose(SOCKET sock)
{
int status = 0;
#ifdef _WIN32
status = shutdown(sock, SD_BOTH);
if (status == 0) { status = closesocket(sock); }
#else
status = shutdown(sock, SHUT_RDWR);
if (status == 0) { status = close(sock); }
#endif
return status;
}
Run Code Online (Sandbox Code Playgroud)
如果您坚持使用"常用"功能(例如send()
或recv()
)并避免使用平台特定的东西(例如WSAWaitForMultipleEvents()
),那么您应该没问题.