在unix上 一切都是函数read()
的文件 方法,Win32不支持write()
,close()
。< / p>
我想模仿它但不知道如何区分WinSocks2上sock
socket 或 fd 的时间。
//returns 1 if `sock` is network socket,
// 0 if `sock` is file desriptor (including stdio, stderr, stdout), ...
// -1 in none of above
int is_net_socket(int sock)
{
// ...?
}
这应该如下:
int mysock = socket(PF_INET, SOCK_STREAM, 0);
int myfd = _open("my_file.txt", _O_RDONLY);
printf("1: %d 2: %d 3: %d 4:%d\n",
is_net_socket(mysock), //1
is_net_socket(myfd), //0
is_net_socket(stdin), //0
is_net_socket(stderr)); //0
// should print "1: 1 2: 0 3: 0 4:0"
如何实施is_net_socket
以便将其用作:
int my_close(int sock)
{
#if ON_WINDOWS
switch( is_net_socket(sock) ) {
case 1: return closesocket(sock);
case 0: return _close(sock);
default: //handle error...
}
#else
return close(sock);
#endif
}
答案 0 :(得分:10)
不确定您认为Windows不允许您将SOCKET
句柄用作文件的位置 - 正如Socket Handles页面上明确说明的那样:
套接字句柄可以选择是Windows套接字2中的文件句柄.Winsock提供程序的套接字句柄可以与其他非Winsock函数一起使用,如ReadFile,WriteFile,ReadFileEx和WriteFileEx。
无论如何,关于如何在Windows上区分它们,请参阅函数NtQueryObject,如果传递给它的句柄是,则返回句柄名\Device\Tcp
开放SOCKET
。阅读此备注返回的结构的“备注”部分。
请注意,此方法仅适用于XP及以上版本,并且在Windows 2000上会失败(我假设它已经足够大,不会对您产生影响。)
答案 1 :(得分:5)
我想你可以用select来查询套接字的状态。
http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx
我建议将文件desc和套接字分组到一个结构中。您可以声明枚举以告知描述符是文件还是套接字。我知道这可能不像你想要的那样动态,但通常当你创建便携式应用程序时,最好将这些细节抽象出来。
示例:
enum type { SOCKET, FILE };
typedef struct
{
unsigned int id;
type dataType;
} descriptor_t;
int close(descriptor_t sock)
{
#if WIN32
if (sock.dataType == SOCKET)
return closesocket(sock.id);
else
return _close(sock.id);
#else
return close(sock.id);
#endif
}
答案 2 :(得分:3)
我怀疑......但我不确定,Windows上的fds和套接字使用不同的命名空间。因此,套接字和文件的编号可能相同,当您拨打is_net_socket
时,无法知道您正在谈论的是哪一个。
尝试打印出socket和fd号码,看看它们是否在同一时间彼此相同。
答案 3 :(得分:3)
如果Windows“C”库有dup(),你可以尝试复制它,这对于套接字来说应该是失败但是对于文件fd是成功的。所以:
int is_net_socket(fd)
{
return close(dup(fd)) != 0;
}
警告:未经测试的理论与未经测试的依赖关系;-)请注意,如果用完fd,这将返回误导性结果。另一个副作用是,如果它是一个文件,它将被刷新并更新其目录条目。总而言之,坦率地说它可能很糟糕。我甚至可能会自己投票。