These functions either return a local protocol address (GETSOCKNAME) that is associated with a socket, or return the address of a foreign protocol associated with a socket (getpeername).
#include <sys/socket.h>
int getsockname (int sockfd,struct sockaddr* localaddr,socklen_t *addrlen);
int getpeername (int sockfd,struct sockaddr* peeraddr,socklen_t *addrlen);
All returns: If the success is 0, the failure is 1
Getpeername is called only after the connection is established, otherwise the address and port will not be obtained correctly, so its parameter descriptor is generally a connected descriptor rather than a listener socket descriptor.
UDP without a connection cannot invoke getpeername, but it can call getsockname and TCP, and its address and port are not specified in the call socket, but after the first call to the SendTo function.
Already connected UDP, after calling connect, these 2 functions (Getsockname,getpeername) are available. But this is not very meaningful because the UDP already connected (connect) already knows the other person's address.
These two functions are required for the following reasons:
On a TCP client that does not call bind, the getsockname is used to return the local IP address and local port number given to the connection by the kernel when connect is successfully returned.
After calling bind with a port number of 0 (telling the kernel to select the local temporary port number), GetSockName is used to return the local port number given by the kernel.
On a TCP server that calls bind with a wildcard IP address, once a connection to a client is established (accept successfully returned), GetSockName can be used to return the local IP address given to the connection by the kernel. In such a call, the socket descriptor parameter must be a descriptor for the connected socket, not a descriptor for the listening socket.
When a server is a process called exec executing a program by calling accept, the only way it can acquire a client's identity is by invoking Getpeername.
For example, the inetd call accept (the box at the top left) returns two values: the socket descriptor CONNFD is connected, which is the return value of the function, the client's IP address and port number, as shown in the small box with the "to end address" in the figure (representing an internetwork socket address structure). Inetd then calls fork and derives a subprocess of the inetd. The socket address structure of the parent process is also available in the child process, as is the connected socket descriptor. However, when the child process invokes exec to execute a real server program (say, telent server program), the memory image of the child process is replaced with the program file of the new Telnet server (that is, the socket address structure that contains the End-to-end address is discarded). But that connected socket descriptor continues to remain open across exec. One of the functions that the Telnet server calls first is Getpeername
, which is used to obtain the customer's IP address and port number.
Obviously, the Telnet server in the last example must obtain the CONNFD value after startup. There are two common ways to get this value:
A process called exec can format this descriptor as a string and pass it as a command-line argument to the new program.
A convention always puts a specific descriptor as the descriptor of the accepted concatenated socket before calling exec.
INETD uses the second method, which always sets descriptors 0, 1, and 2 to the accepted descriptor for the connected socket (the connection socket descriptor is DUP to descriptors 0, 1, 2, and then close the original connection socket).
See more highlights of this column: http://www.bianceng.cnhttp://www.bianceng.cn/OS/unix/