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