Recovering IP/Port from Socket Descriptor

前端 未结 3 650
生来不讨喜
生来不讨喜 2021-01-05 03:46

I\'m writing a clone of inetd in which I must run a server that prints the IP and port of the client connecting to it.

As I overwrite STDIN and S

相关标签:
3条回答
  • 2021-01-05 04:14

    Use getpeername. I suspect your problem is that getsockname is returning the information for your own (local) side of the socket, which is probably bound to 0.0.0.0 (meaning it can accept connections from any interface).

    Edit: I think I found your actual bug reading the code. This line is wrong:

    getsockname(stdin, &addr, sizeof(addr));
    

    The getsockname and getpeername functions take a socklen_t * (a pointer) as their third argument, not a size_t. The compiler should be telling you about this mistake unless you forgot to include a header with the prototype for getsockname. Also, as has already been said, stdin is incorrect. Try:

    socklen_t len = sizeof addr;
    getpeername(0, &addr, &len);
    

    or (C99 only):

    getpeername(0, &addr, (socklen_t[1]){sizeof addr});
    

    You should also be checking the return value; if you did, you'd see that it's returning errors.

    0 讨论(0)
  • 2021-01-05 04:25

    If you need those info for the remote client, you have to call getpeername().

    0 讨论(0)
  • 2021-01-05 04:36

    As R.. pointed out, you should use getpeername. Both that function and getsockname take a file descriptor as its first argument, not a stream pointer (FILE *). Use fileno(stdin) to get the file descriptor for standard input (or hard-code it to STDIN_FILENO, as it's constant).

    Also, the last argument to getsockname and getpeername should be a pointer to socklen_t, not a constant, and you should use a sockaddr_in for TCP/IP:

    struct sockaddr_in peeraddr;
    socklen_t peeraddrlen = sizeof(peeraddr);
    getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);
    

    See a complete example here.

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