日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络信息相关函数

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络信息相关函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

gethostbyname和gethostbyaddr

gethostbyname根據主機名稱獲取主機的完整信息,gethostbyaddr根據IP地址獲取主機的完整信息。

gethostname通常先在本地/etc/hosts配置文件查找,如果沒有再向DNS服務器查找。

#include <unistd.h> #include <sys/socket.h>int gethostname(char *name, size_t len);struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); struct hostent {char *h_name; /* 主機名 */char **h_aliases; /* 主機別名列表 */int h_addrtype; /* 地址類型 */int h_length; /* 地址長度 */char **h_addr_list; /* ip地址列表 */ }

name參數指定目標主機名,addr參數指定目標主機的IP地址,len參數指定addr的地址大小,type參數指定addr所指IP地址的類型。

代碼實現:根據主機名baidu和百度的ip地址獲取百度的信息。

getservbyname和getservbyport

#include <netdb.h>struct servent *getservent(void); struct servent *getservbyname(const char *name, const char *proto); struct servent *getservbyport(int port, const char *proto);

getservbyname函數根據名稱獲取某個服務的完整信息。

getservbyport函數根據端口號獲取某個服務的完整信息。

name參數指定服務名字。
port參數指定目標服務對應的端口號。
proto參數指定服務類型。

函數返回的都是servent指針,結構體servent定義如下:

struct servent {char *s_name; /* 服務名稱 */char **s_aliases; /* 服務別名列表 */int s_port; /* 端口號 */char *s_proto; /* 服務類型 */ }

代碼:編寫一個程序,使用主機名和服務名訪問目標服務器上的daytime服務,獲取該機器的系統時間。

#include <iostream> #include <netdb.h> #include <unistd.h> #include <assert.h> #include <cstring> using namespace std;int main(int argc, char* argv[]) {/* 主函數需要1個參數 */assert(argc == 2);char* host = argv[1];/* 獲取目標主機的地址信息 */hostent* hostinfo = gethostbyname(host);assert(hostinfo);/* 獲取daytime服務信息 */servent* servinfo = getservbyname("daytime", "tcp");assert(servinfo);printf("daytime port is %d\n", servinfo->s_port);/* 創建socket地址 */sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = servinfo->s_port;addr.sin_addr = *(in_addr*)*hostinfo->h_addr_list;/* 創建socket文件描述符 */int sockfd = socket(AF_INET, SOCK_STREAM, 0);assert(sockfd >= 0);/* 連接 */int ret = connect(sockfd, (sockaddr*)&addr, sizeof addr);assert(ret != -1);/* 數據讀寫 */char buffer[128];memset(buffer, '\0', sizeof buffer);ret = read(sockfd, buffer, sizeof buffer);assert(ret > 0);printf("the day is: %s\n", buffer);/* 關閉socket */close(sockfd);return 0; }

注意上面四個函數是不可重入的,非線程安全,netdb.h給出了可重入版本,在原函數尾部加上_r即可。

./a.out localhost daytime port is 3328 a.out: GetSysTime.cpp:35: int main(int, char**): Assertion `ret != -1' failed. [1] 30605 abort (core dumped) ./a.out localhost

失敗在連接這一步,這是因為默認xinetd是關閉daytime的修改配置文件

service daytime {disable = notype = INTERNALid = daytime-streamsocket_type = streamprotocol = tcpuser = rootwait = no }# This is the udp version. service daytime {disable = notype = INTERNALid = daytime-dgramsocket_type = dgramprotocol = udpuser = rootwait = yes }

disable = yes 改成disable = no,上圖所示,并重啟xinetd。

sudo systemctl restart xinetd.service

查看是否服務已經啟動

sudo systemctl status xinetd.service ● xinetd.service - LSB: Starts or stops the xinetd daemon.Loaded: loaded (/etc/init.d/xinetd; generated)Active: active (running) since Mon 2021-10-04 02:59:02 PDT; 17s agoDocs: man:systemd-sysv-generator(8)Process: 30709 ExecStart=/etc/init.d/xinetd start (code=exited, status=0/SUCCESS)Tasks: 1 (limit: 2273)Memory: 364.0KCGroup: /system.slice/xinetd.service└─30734 /usr/sbin/xinetd -pidfile /run/xinetd.pid -stayalive -inetd_compat>

開啟服務后,再次嘗試:

./a.out localhost daytime port is 3328 the day is: 04 OCT 2021 03:01:07 PDT

雖然中間遇到一些小問題,最終還是解決了。

getaddrinfo

#include <netdb.h>int getaddrinfo(const char *node, const char *service,const struct addrinfo *hints,struct addrinfo **res);

此函數既能通過主機名獲得IP地址,也能通過服務名獲取端口號。此函數是否可重用取決于內部調用的是gethostbyname和getservbyname函數的可重入版本。
hostname可以接收主機名,也可以表示接收字符串表示的IP地址。
service可以接收服務名,也可以接收端口號。
hints參數三十應用程序給addrinfo的一個提示,以對getaddrinfo的輸出進行更加精準的控制。

struct addrinfo {int ai_flags; /* 標志 */int ai_family; /* 地址族 */int ai_socktype; /* 服務類型 */int ai_protocol; /* 網絡協議 */socklen_t ai_addrlen; /* socket地址長度 */struct sockaddr *ai_addr; /* 主機別名 */char *ai_canonname; /* 指向socket地址 */struct addrinfo *ai_next; /* 指向下一個sockinfo結構的對象 */ };


使用hints參數的時候,可以設置ai_flagsai_familyai_socktypeai_protocol四個字段,其它字段必須設置為NULL。

... struct addrinfo hints; struct addrinfo* res;bzero(&hints, sizeof hints); hints.ai_socktype = SOCK_STREAM; getaddrinfo("localhost", "daytime", &hints, &res);

getaddrinfo隱士分配內存。調用結束后使用下面函數釋放內存

#include <netdb.h>void freeaddrinfo(struct addrinfo* res);

getnameinfo

總結

以上是生活随笔為你收集整理的网络信息相关函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。