In socket programming, the server accept () waits for a client connection. After the connection is successful, accept copies the client address information to sin_addr, how can we obtain the IP address and port number of the client from sin_addr?
In fact, when sockaddr_in.sin_family = af_inet, sockaddr = sockaddr_in.
Therefore, we can use inet_ntoa () to obtain the IP address and port number:
Int new_fd = accept (sock, & clientaddr, & sin_size );
If (new_fd <0)
{
Char MSG [64];
Bzero (MSG, sizeof (MSG ));
Sprintf (MSG, "Accept failed ");
Log: outputsyserr (MSG );
}
Else
{
// Forcibly convert sockaddr to sockaddr_in
Sockaddr_in sin;
Memncpy (& sin, & clientaddr, sizoef (SIN ));
// Obtain the IP address and port number
Sprintf (info. IP, inet_ntoa (SIN. sin_addr ));
Info. Port = sin. sin_port;
Info. Sock = new_fd;
}
Does the "Conversion" mentioned above seem strange? In fact, you can use a forced conversion:
Sockaddr_in * pSIN = (sockaddr_in *) & clientaddr;
The first method indirectly means that they occupy the same memory size. When sockaddr_in.sin_family = af_inet, their memory layout is the same! You can see the sockaddr struct itself. It is just a char array and the size is the same as that of sockaddr_in:
/* Structure describing a generic socket address .*/
Struct sockaddr
{
_ Sockaddr_common (SA _);/* Common Data: address family and length .*/
Char sa_data [14];/* address data .*/
};
The structure of sockaddr_in is defined as follows:
/* Structure describing an internet socket address .*/
Struct sockaddr_in
{
_ Sockaddr_common (SIN _);
In_port_t sin_port;/* port number .*/
Struct in_addr sin_addr;/* Internet address .*/
/* Pad to size of 'struct sockadd '.*/
Unsigned char sin_zero [sizeof (struct sockaddr )-
_ Sockaddr_common_size-
Sizeof (in_port_t )-
Sizeof (struct in_addr)];
};
/* Ditto, for example 6 .*/
Struct sockaddr_in6
{
_ Sockaddr_common (sin6 _);
In_port_t sin6_port;/* Transport Layer port #*/
Uint32_t sin6_flowinfo;/* IPv6 Flow Information */
Struct in6_addr sin6_addr;/* IPv6 address */
Uint32_t sin6_scope_id;/* IPv6 scope-ID */
};