首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

2.5.2 平台独立的定义

由于Sockets API 库和Winsock库在某些方面有差异,所以需要创建一种方法,使得无论采用哪种实现方法,代码都可以运行。由于各种API几乎相同,所以这很容易办到。

在这一点上,可以有若干种选择方案,例如,任何时候想要关闭套接字时都可以如下所示这么做。

#ifdef WIN32

    closesocket( sock );

#else

    close( sock );

#endif

这种方法稍微有点乱,除非是将关闭套接字的代码单独分离出来,在第4章中创建一个套接字包装器后就是这么做的。但是,暂时采用的这种方法是一种比较笨也不太容易理解的方法。下面介绍另一种方法,将这些代码称为“代码块2.2(Code Block 2.2)”:

// 代码块2.2 —— 为交互兼容性进行重新定义和全局化处理

#ifdef WIN32                // Windows 95 及以上

    WSADATA g_wsadata;      // Winsock数据持有者

    #define CloseSocket closesocket

    #define GetSocketError WSAGetLastError

    #define StartSocketLib WSAStartup( MAKEWORD( 2, 2 ), &g_wsadata );

    #define CloseSocketLib WSACleanup();

    #ifndef socklen_t

        typedef int socklen_t;

    #endif

#else                       // UNIX/Linux

    #define CloseSocket close

    #define GetSocketError errno

    #define StartSocketLib {}

    #define CloseSocketLib {}

#endif

// 结束代码块 2.2 —— 为交互兼容性进行重新定义和全局化处理

因为Winsock需要一个WSADATA结构,所以在WIN32分支代码中定义了一个WSADATA结构。接下来的4行在Winsock和Sockets API中有差异。在Windows分支的代码段中,宏CloseSocket只是closesocket的另一个名称(注意区分大小写);而在Linux分支的代码段中,它是close的另一个名称。GetSocketError的情况与此相同,根据不同的系统,它的别名可能是WSAGetLastError,也可能是errno。

最后两行定义了套接字库的初始化和停止阶段,在Winsock中有内容,但在Socket API中则没有内容。因此,StartSocketLib的Windows版本称为WSAStartup;而UNIX版本则根本没有任何内容(只是一对空括号)。

Windows代码块另外还有3行代码。这是因为有些旧的Winsock版本中没有定义socklen_t数据类型。因此,只要函数检测到它不存在,就可以简单地将它定义为int。许多套接字函数都需要socklen_t。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论