判断socket和fd之间的关系

发布于 2024-11-17 07:23:00 字数 1126 浏览 3 评论 0原文

在unix上,一切都是文件函数read()write()close( ) 在 Win32 上不受支持。

我想模拟它,但不知道如何区分WinSocks2上的socksocket还是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
}

On unix everything is a file approach of function read(), write(), close() is not supported on Win32.

I want to emulate it but have no idea how to distinguish when sock is socket or fd on 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)
{
    // ...?
}

This should work as in :

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"

How to implement is_net_socket in order to use it as in:

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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别念他 2024-11-24 07:23:00

不确定您从哪里得到这样的想法:Windows 不允许您将 SOCKET 句柄用作文件 - 正如 套接字句柄 页面:

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

无论如何,至于如何在 Windows 上区分它们,请参阅函数 NtQueryObject,如果传递给它的句柄是一个开放的 SOCKET,它将返回 \Device\Tcp 的句柄名称>。请阅读“备注”部分以了解此调用返回的结构。

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

Not sure where you're getting the idea that Windows won't allow you to use SOCKET handles as files - as clearly stated on the Socket Handles page:

A socket handle can optionally be a file handle in Windows Sockets 2. A socket handle from a Winsock provider can be used with other non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and WriteFileEx.

Anyways, as to how to distinguish between them on Windows, see the function NtQueryObject, which will return a handle name of \Device\Tcp if the handle passed to it is an open SOCKET. Read the "Remarks" section for the structure returned by this call.

Note that this approach only works XP and up, and will fail on Windows 2000 (which I'm assuming is old enough that it doesn't affect you.)

深海蓝天 2024-11-24 07:23:00

我想你可以使用 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
}

I suppose you can use select to query the status of a socket.

http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx

I would recommend grouping your file desc and sockets in a single struct. You can declare an enum to tell if the descriptor is a file or socket. I know this might not be as dynamic as you want, but generally when you create portable applications, its best to abstract those details away.

Example:

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
}
甜心小果奶 2024-11-24 07:23:00

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

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

I suspect... but I am not sure, that fds and sockets on Windows use separate namespaces. Therefore the number for a socket and a file could be the same, and it is impossible to know which one you are talking about when you call is_net_socket.

Try printing out socket and fd numbers to see if they are ever the same as each other at the same time.

苏别ゝ 2024-11-24 07:23:00

如果 Windows 'C' 库有 dup(),您可以尝试复制它,这对于套接字应该失败,但对于文件 fd 会成功。所以:

int is_net_socket(fd)
{
  return close(dup(fd)) != 0;
}

警告:未经测试的理论与未经测试的依赖关系;-) 请注意,如果您用完 fd,这将返回误导性的结果。另一个副作用是,如果它是一个文件,它将被刷新并更新其目录条目。总而言之,坦率地说,这可能很糟糕。我什至可能自己投反对票。

If the Windows 'C' library has dup() you could try to dup it, which should fail for a socket but succeed for a file fd. So:

int is_net_socket(fd)
{
  return close(dup(fd)) != 0;
}

Warning: untested theory with untested dependency ;-) Note that this would return misleading results if you run out of fd's. Another side effect is that if it is a file it will be flushed and its directory entry updated. All in all it probably sucks frankly. I might even downvote it myself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文