在socket和fd之间确定

Din*_*lla 15 c sockets windows winsock winsock2

在Unix 一切都是文件的函数方法read(),write(),close()不支持在Win32.

我想效仿,但不知道如何时区分sock插座FD上WinSocks2.

//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)
{
    // ...?
}
Run Code Online (Sandbox Code Playgroud)

这应该如下:

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"
Run Code Online (Sandbox Code Playgroud)

如何实现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
}
Run Code Online (Sandbox Code Playgroud)

TkT*_*ech 10

不知道你在哪里认为Windows不允许你使用SOCKET句柄作为文件 - 如套接字句柄页面上明确说明的那样:

套接字句柄可以选择是Windows套接字2中的文件句柄.来自Winsock提供程序的套接字句柄可以与其他非Winsock函数一起使用,例如ReadFile,WriteFile,ReadFileEx和WriteFileEx.

无论如何,关于如何在Windows上区分它们,请参阅函数NtQueryObject,\Device\Tcp如果传递给它的句柄是打开的,它将返回句柄名称SOCKET.阅读此备注返回的结构的"备注"部分.

请注意,此方法仅适用于XP及以上版本,并且在Windows 2000上会失败(我假设它已经足够大,不会影响您.)


小智 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
}
Run Code Online (Sandbox Code Playgroud)


Die*_*Epp 3

我怀疑......但我不确定,Windows 上的 fds 和套接字使用单独的名称空间。因此,套接字和文件的编号可能相同,并且当您调用时不可能知道您正在谈论哪个is_net_socket

尝试打印出套接字和文件描述符编号,看看它们是否同时彼此相同。