The function gethostbyaddr takes a binary IPv4 address and tries to find the hostname corresponding to that address. This is the reverse of gethostbyname.
#include
struct hostent *gethostbyaddr (const char *addr, socklen_t len, int family);
Services, like hosts, are often known by names, too. If we refer to a service by its name in our code, instead of by its port number, and if the mapping from the name to port number is contained in a file (normally /etc/services), then if the port number changes, all we need to modify is one line in the /etc/services file instead of having to recompile the applications. The next function, getservbyname, looks up a service given its name.
#include
struct servent *getservbyname (const char *servname, const char *protoname);
This function returns a pointer to the following structure:
struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s-port; /* port number, network-byte order */
char *s_proto; /* protocol to use */
};
The service name servname must be specified. If a protocol is also specified (protoname is a non-null pointer), then the entry must also have a matching protocol.
The next function, getservbyport, looks up a service given its port number and an optional protocol.
#include
struct servent *getservbyport (int port, const char *protoname);
#include "unp.h"
int main(int argc, char **argv)
{
int sockfd, n;
char recvline[MAXLINE+1];
struct sockaddr_in servaddr;
struct in_addr **ptr;
struct in_addr *inetaddrp[2];
struct in_addr inetaddr;
struct hostent *hp;
struct servent *sp;
if(argc!=3){
err_quit("usage: daytimetcpclientl ");
}
if((hp=gethostbyname(argv[1]))==NULL)
{
if(inet_aton(argv[1],&inetaddr)==0)
{
err_quit("hostname error for %s: %s",argv[1], hstrerror(h_errno));
}else{
inetaddrp[0]=&inetaddr;
inetaddrp[1]=NULL;
pptr=inetaddrp;
}
}
else
{
pptr=(struct in_addr **)hp->h_addr_list;
}
if((sp=getservyname(argv[2],"tcp"))==NULL)
{
err_quit("getservbyname error for %s", argv[2]);
}
for(;*pptr!=NULL;pptr++)
{
sockfd=Socket(AF_INET, SOCK_STREAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=sp->s_port;
memcpy(&servaddr.sin_addr, *pptr, sizeof9struct in_addr));
printf("trying %s\n", Sock_ntop((SA *)&servaddr, sizeof(servaddr)));
if(connect(sockfd, (SA *)&servaddr, iszoef9servaddr))==0)
break;
err_ret("connect error");
close(sockfd);
}
if(*pptr==NULL)
{
err_quit("unable to connect");
}
while((n=Read(sockfd, recvline,MAXLINE))>0)
{
recvlien[n]=0;
Fputs(recvline, stdout);
}
return 0;
}
Our daytime client that uses gethostbyname and getservbyname