Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 跨平台插座_C_Sockets - Fatal编程技术网

C 跨平台插座

C 跨平台插座,c,sockets,C,Sockets,我知道,Windows不使用UNIX套接字,而Mac OS使用。在此之前,我的软件是跨平台的,没有任何代码更改。但是现在我想让它做一些网络通信。我知道POSIX套接字,但我对Windows的套接字一无所知。目标是实现一个简单的跨平台套接字服务器 请您向我解释一下POSIX和Winsock套接字之间的区别,以及我可以如何编写跨平台网络代码?有许多支持跨平台套接字的库和工具包,根据您所做的工作,您可以使用(举几个例子): openssl apache可移植运行时 libtcl 如果您不想依赖外部

我知道,Windows不使用UNIX套接字,而Mac OS使用。在此之前,我的软件是跨平台的,没有任何代码更改。但是现在我想让它做一些网络通信。我知道POSIX套接字,但我对Windows的套接字一无所知。目标是实现一个简单的跨平台套接字服务器


请您向我解释一下POSIX和Winsock套接字之间的区别,以及我可以如何编写跨平台网络代码?

有许多支持跨平台套接字的库和工具包,根据您所做的工作,您可以使用(举几个例子):

  • openssl
  • apache可移植运行时
  • libtcl
如果您不想依赖外部库,则上述所有软件包都具有相当许可的许可证,因此您可以使用它们的代码作为参考。

构建套接字服务器所需的常规套接字(位于AF_INET address系列中的套接字)在所有平台上都受到同等支持

不要将它们与Unix套接字(AF_Unix address系列中的那些)混淆—这些套接字对于Unix世界是非常特定的,并且用于非常特定的目标。简单的套接字服务器应用程序永远不需要它们。

WinSock与POSIX套接字 插座的工作方式类似-主要原因是:

尽管这些专有的BSD衍生产品在20世纪90年代基本上被UNIX System V Release 4和OSF/1系统所取代(这两个系统都包含BSD代码,并且是其他现代UNIX系统的基础),但后来的BSD版本为几个开源开发项目提供了基础,例如FreeBSD、OpenBSD、NetBSD、Darwin或PC-BSD,这是正在进行的。这些,反过来,已经全部或部分地结合在现代专有操作系统中,例如<强> TCP/IP(IPv4)网络代码在微软Windows 以及苹果OS X和iOS的基础。 但是,如果您想编写“套接字库不可知”代码,则需要以不同的方式处理一些事情

注意:以下示例已在Windows XP(x86)和Debian测试(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
套接字句柄在Winsock上未签名 对于POSIX样式的套接字,您可以简单地使用
int
来存储套接字句柄。无效套接字由负值表示

但是,使用一个特殊常量(
无效的\u SOCKET
)代替负数

您可以通过在POSIX上将套接字设置为
int
,并在宏或函数后面隐藏“valid SOCKET”检查来提取差异

插座的闭合方式不同 下面的函数说明了这些区别:

/* 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()
),并避免使用特定于平台的东西(如),那么您应该没问题。

我还可以建议使用该库:在Windows和UNIX系统上都可以使用(请参阅项目页面上的完整列表),并使用各种编译器。支持IPv4和IPv6。它有一些测试,您可以在其中看到使用示例。库本身是轻量级和可移植的。

它超越了纯套接字,但我发现0mq(ZeroMq)非常有趣。我通常做的是,在Cygwin下使用POSIX程序和gcc编译,然后像那样分发;-)额外的好处:它让我在Windows上的生活变得更加轻松。不幸的是(?)这里有问题和建议。但是,一种解决方案是使用Cygwin(如果您需要其他类似Unix的基础设施)或Mingw(如果您的程序不需要“假Unix”环境,只需要C库/API就足够)直接构建Unix/Linux源代码。这类问题非常有用,抱歉,它被关闭了。另一个区别是Windows的
WinSock
不能很好地处理POSIX套接字可以正常工作的基本
read()
write()
调用。例如,在WinSock上调用
write(socket,buffer,bytes)
可能会失败,而在完全相同的套接字上调用
send(socket,buffer,bytes,0)
可以正常工作。为什么你要让OP链接到WinSock 2并告诉他们如何清理WinSock 1套接字?@rstackhouse升级到
/* 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;

}