Services are represented by the port number portion of the address. Each service is offered on a unique, well-known port number. We can map a service name to a port number withgetservbyname, map a port number to a service name withgetservbyport, or scan the services database sequentially withgetservent.(APUE-2e)

地址的端口部分和服务是一一对应的,getservbyname()和 getservbyport()能将二者相互映射(map)。

/* Description of data base entry for a single service.  */
struct servent
{
  char *s_name;			/* Official service name.  */
  char **s_aliases;		/* Alias list.  */
  int s_port;			/* Port number.  */
  char *s_proto;		/* Protocol to use.  */
};
struct servent *getservent(void);
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
void setservent(int stayopen);
void endservent(void);

说明:

(1) 这几个函数的原理是查询 /etc/services 文件(ubuntu下)

(2) s_port is in network byte order, you should usentohs()(not htohl(), I don't know why) to convert it to host byte order.

/**
 * getservent()
 * OS: Ubuntu 11.04 Server
 */
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>


static void printserv(struct servent *serv);


int main()
{
	struct servent *serv = NULL;
	setservent(1);
	while( (serv = getservent()) != NULL )
	{
		printserv(serv);
		printf("\n");
	}
	endservent();
	return 0;
}
static void printserv(struct servent *serv)
{
	char **p = NULL;
	
	printf("service name: %s\n", serv->s_name);
	
	for(p = serv->s_aliases; *p != NULL; p++)
	{
		printf("aliase: %s\n", *p);
	}
	
	printf("port number: %d\n", ntohs(serv->s_port));	// Note: the port here is in network byte order.
	//printf("port number: %x\n", serv->s_port);
	//printf("port number: %d\n", ntohl(serv->s_port));	// Note: use ntohs(), not ntohl(), I don't know why.
	
	printf("protocol: %s\n", serv->s_proto);
}
/*
output:
service name: tcpmux
port number: 256
protocol: tcp


service name: echo
port number: 1792
protocol: tcp


service name: echo
port number: 1792
protocol: udp


...


/etc/services:
tcpmux          1/tcp                           # TCP port service multiplexer
echo            7/tcp
echo            7/udp
...
*/