/*******************************************************************************
函数原型: struct hostent* gethostbyname(const char* name)
函数说明:通过主机名调用gethostbyname返回包含主机正式名称,主机别名,IPV4地址等信息的结构体
返回值: 若成功返回struct hostent*,出错返回NULL,并修改全局变量h_errno,不修改errno
**********************************************************************************/
/***********************************************************************************
struct hostent {
char* h_name;//主机正式规范名称
char** h_aliases;//主机别名
int h_addrtype; //主机地址类型
int h_length;//地址长度
char** h_addr_list;//地址列表(IPV4)
}
***********************************************************************************/
/***********************************************************************************
函数原型: struct servent* getservbyname(const char* name,const char*protoname)
函数说明:通过服务名+使用协议(若为NULL,得到结构体采用协议依赖实现),得到包含正式服务名,服务别名,服务端口,服务使用协议等信息的结构体
返回值:若成功,返回struct servent*,若失败,返回NULL
***********************************************************************************/
/**********************************************************************************
struct servent {
char *s_name; //正式服务名
char** s_aliases;//服务名别名
char* s_port;//服务端口号
char* s_proto;//服务采用协议
}
**********************************************************************************/
应用:通过TCP C/S获取时间 :
服务器代码:(从别的主机获取时要确保它们的标准时间服务器端口已打开):
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#define PORT 13
#define LISTENQ 100
void sig_child(int signo) {
int ppid;
while ((ppid = waitpid(-1,NULL,WNOHANG)) < 0) {
printf("waitpid error: %s\n",strerror(errno));
exit(1);
}
}
void server_echo(int fd) {
char str[128];
time_t t = time(NULL);
strftime(str,sizeof(str),"%Y %x %X",localtime(&t));
int len = strlen(str);
str[len] = '\n';
str[len + 1] = '\0';
if (write(fd,str,strlen(str)) != strlen(str)) {
printf("write error: %s\n",strerror(errno));
exit(1);
}
}
int main() {
int sockfd;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
printf("socket error: %s\n",strerror(errno));
exit(1);
}
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_in)) < 0) {
printf("bind error: %s\n",strerror(errno));
exit(1);
}
if (listen(sockfd,LISTENQ) < 0) {
printf("listen error: %s\n",strerror(errno));
exit(1);
}
if (signal(SIGCHLD,sig_child) == SIG_ERR) {
printf("signal error: %s\n",strerror(errno));
exit(1);
}
int connfd;
int pid;
for (; ;) {
if ((connfd = accept(sockfd,NULL,NULL)) < 0) {
if (errno == EINTR) {
continue;
}
printf("accept error: %s\n",strerror(errno));
}
if ((pid = fork()) < 0) {
printf("fork error: %s\n",strerror(errno));
exit(1);
}else if (pid == 0) {
close(sockfd);
server_echo(connfd);
close(connfd);
exit(0);
}
close(connfd);
}
return 0;
}
客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 4096
int main(int argc,char **argv) {
if (argc != 3) {
printf("add <hostname> <serveices>\n");
exit(1);
}
struct hostent* host;
struct in_addr** ppaddr;
struct in_addr* addr[2];
struct in_addr initaddr;
if ((host = gethostbyname(argv[1])) == NULL) {
if (inet_pton(AF_INET,argv[1],&initaddr) <= 0) {
printf("gethostbyname error: %s\n",hstrerror(h_errno));
exit(1);
}else {
addr[0] = &initaddr;
addr[1] = NULL;
ppaddr = addr;
}
}else {
ppaddr = (struct in_addr**)host->h_addr_list;
}
struct servent* service;
if ((service = getservbyname(argv[2],NULL)) == NULL) {
printf("getservbyname error\n");
exit(1);
}
int sockfd;
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = service->s_port;
for (; *ppaddr != NULL; ++ppaddr) {
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
printf("socket error: %s\n",strerror(errno));
exit(1);
}
memcpy(&serveraddr.sin_addr,*ppaddr,sizeof(struct in_addr));
char str[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET,&serveraddr.sin_addr,str,sizeof(str)) == NULL) {
printf("inet_ntop error: %s\n",strerror(errno));
exit(1);
}
printf("trying to connect IP: %s port: %d\n",str,ntohs(serveraddr.sin_port));
if (connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_in)) == 0) {
printf("connect to IP: %s port success: %d\n",str,ntohs(serveraddr.sin_port));
break;
}
printf("connect to IP: %s port: %d failed reason: %s\n",str,ntohs(serveraddr.sin_port),strerror(errno));
}
if (*ppaddr == NULL) {
printf("all connect failed\n");
}
char recv[BUFSIZE];
int n;
while ((n = read(sockfd,recv,BUFSIZE)) > 0) {
if (write(STDOUT_FILENO,recv,n) != n) {
printf("write error: %s\n",strerror(errno));
exit(1);
}
}
return 0;
}
运行: