Determine between socket and fd

后端 未结 4 683
挽巷
挽巷 2021-02-13 06:04

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

I

相关标签:
4条回答
  • 2021-02-13 06:37

    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.

    0 讨论(0)
  • 2021-02-13 06:42

    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.)

    0 讨论(0)
  • 2021-02-13 06:50

    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
    }
    
    0 讨论(0)
  • 2021-02-13 06:58

    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.

    0 讨论(0)
提交回复
热议问题