gethostbyname函式和getservbyname函式的應用
/*******************************************************************************
函式原型: 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;
}
執行:
相關文章
- 函式柯里化和偏函式應用函式
- C/C++的mem函式和strcopy函式的區別和應用C++函式
- Vue函式式元件的應用Vue函式元件
- Excel函式應用教程:函式的引數(轉)Excel函式
- 尤拉函式的應用函式
- Excel函式應用教程:函式的輸入方法(轉)Excel函式
- Excel函式應用教程:函式與公式的概念(轉)Excel函式公式
- 字元函式、數字函式和日期函式字元函式
- Hash函式及其應用函式
- Rust中的into函式和from函式Rust函式
- ascii函式和substr函式的用法ASCII函式
- 函式宣告和函式表示式的區別函式
- 鴻蒙HarmonyOS實戰-Web元件(前端函式和應用側函式相互呼叫)鴻蒙Web元件前端函式
- Java 函式式介面 lamada 應用Java函式
- 損失函式+啟用函式函式
- javascript高階函式的應用JavaScript函式
- Python的sorted函式應用Python函式
- prop()函式和attr()函式的區別函式
- C++的函式和模板函式 (轉)C++函式
- strcpy函式和memcpy函式的區別函式memcpy
- 類函式和物件函式 PHP函式物件PHP
- 如何使用函式指標呼叫類中的函式和普通函式函式指標
- Generator函式非同步應用函式非同步
- 函式計算——應用初探函式
- 函式進階應用3函式
- Oracle OCP(03):字元函式、數字函式和日期函式Oracle字元函式
- Oracle translate函式和正則的幾個應用Oracle函式
- JavaScript函式宣告和函式表示式區別JavaScript函式
- JavaScript中的compose函式和pipe函式JavaScript函式
- jquery position()函式和offset()函式的區別jQuery函式
- # 普通函式和箭頭函式的區別函式
- 函式防抖和函式節流函式
- 函式基礎和函式引數函式
- Python strip函式和split函式Python函式
- 指標函式 和 函式指標指標函式
- jquery的$.each()函式和$.map()函式的區別jQuery函式
- MySQL 日期函式、時間函式在實際場景中的應用MySql函式
- StretchBlt函式和BitBlt函式的區別和用法函式