跨平台插座[英] Cross-platform sockets

本文是小编为大家收集整理的关于跨平台插座的处理方法,想解了跨平台插座的问题怎么解决?跨平台插座问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我知道,在Mac OS时,Windows不使用Unix插座.在此之前,我的软件跨平台没有任何代码更改.但是现在我希望它进行一些网络通信.我知道POSIX插座,但我对Windows的插座一无所知.目标是实现一个简单的跨平台套接字服务器.

您能否向我解释Posix和Winsock插座之间的区别,以及我如何编写跨平台网络代码?

推荐答案

Winsock与POSIX插座

winsock winsock =" http://pubs.opengroup.org/onlinepubs/96999919799/basedefs/sys_socket.h.html"> posix 插座以类似的方式工作 - 主要是因为 Windows插座最初是基于BSD的代码:

尽管这些专有的BSD衍生物在很大程度上被UNIX System V Release 4和OSF/1系统在1990年代(两者都纳入BSD代码,并且是其他现代Unix系统的基础),但后来的BSD版本提供了一个基础对于几个开源开发项目,例如正在进行的FreeBSD,OpenBSD,NetBSD,Darwin或PC-BSD.反过来,这些已被整体或部分合并到现代专有操作系统中,例如 Microsoft Windows中的TCP/IP(仅IPv4)网络代码以及Apple OS X和iOS的大部分基础.

但是,如果您想编写"套接字折线 - 敏捷"代码,您需要以不同的方式处理一些事情.

注意:以下示例已使用Windows XP(X86)和Debian Testing(AMD64)上的Code :: Blocks和GCC进行了测试.

标题和LIB文件不同

您需要根据是否使用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

您还需要与Windows上的Ws2_32 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
}

插座手柄在Winsock上未签名

对于Posix风格的插座,您只需使用int存储插座手柄即可.无效的插座由负值表示.

然而, winsock套接A>,使用特殊常数(INVALID_SOCKET)代替负数.

您可以通过posix上的int typedef ing插座抽象差异,并隐藏"有效套接字"检查宏或函数后面.

插座的关闭方式不同

下面的功能说明了差异:

/* 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;

}

一般而言,它们非常相似.

如果您坚持使用"常见"功能(例如send()或recv())并避免使用平台特定的东西(例如 WSAWaitForMultipleEvents() )然后您应该没事.

其他推荐答案

我也可以建议 plibsys 库:在Windows和Unix Systems上工作(请参阅在项目页面上的完整列表)带有各种编译器.支持IPv4和IPv6.它具有测试,您可以在其中看到使用示例.图书馆本身轻巧且便携.

其他推荐答案

有许多支持跨平台插座的库和工具包,具体取决于您的工作,您可以使用(命名一些):

  • openssl
  • Apache便携式运行时
  • libtcl

如果您不想依赖外部库,则所有上述包都具有相当宽松的许可证,因此您可以将其代码用作参考.

本文地址:https://www.itbaoku.cn/post/359115.html