轉:http://cyuyanbiancheng.blog.hexun.com.tw/56835407_d.html
c語言學習:Linux下的網絡編程(二)
網絡編程(3)
3. Server和Client的信息函數
3. Server和Client的信息函數
這一章我們來學習轉換和網絡方面的信息函數.
3.1 字節轉換函數
在網絡上面有著許多類型的機器,這些機器在表示數據的字節順序是不同的, 比如i386芯 片是低字節在內存地址的低端,高字節在高端,而alpha芯片卻相反. 為了統一起來,在Linux下面,有專門的字節轉換函數.
unsigned long int htonl(unsigned long int hostlong)
unsigned short int htons(unisgned short int hostshort)
unsigned long int ntohl(unsigned long int netlong)
unsigned short int ntohs(unsigned short int netshort)
unsigned short int htons(unisgned short int hostshort)
unsigned long int ntohl(unsigned long int netlong)
unsigned short int ntohs(unsigned short int netshort)
在這四個轉換函數中,
h 代表host,
n 代表 network.
s 代表short
l 代表long
第一個函 數的意義是將本機器上的long數據轉化為網絡上的long. 其他幾個函數的意義也差不多
..
h 代表host,
n 代表 network.
s 代表short
l 代表long
第一個函 數的意義是將本機器上的long數據轉化為網絡上的long. 其他幾個函數的意義也差不多
..
3.2 IP和域名的轉換
在網絡上標誌一臺機器可以用IP或者是用域名.那麽我們怎麽去進行轉換呢?
struct hostent *gethostbyname(const char *hostname)
struct hostent *gethostbyaddr(const char *addr,int len,int type)
在<netdb.h>;中有struct hostent的定義
struct hostent{
char *h_name; /* 主機的正式名稱 */
char *h_aliases; /* 主機的別名 */
int h_addrtype; /* 主機的地址類型 AF_INET*/
int h_length; /* 主機的地址長度 對於IP4 是4字節32位*/
char **h_addr_list; /* 主機的IP地址列表 */
};
char *h_name; /* 主機的正式名稱 */
char *h_aliases; /* 主機的別名 */
int h_addrtype; /* 主機的地址類型 AF_INET*/
int h_length; /* 主機的地址長度 對於IP4 是4字節32位*/
char **h_addr_list; /* 主機的IP地址列表 */
};
#define h_addr h_addr_list[0] /* 主機的第一個IP地址*/
gethostbyname(): 可以將機器名(如 linux.yessun.com)轉換為一個結構指針.在這個結構裏 面儲存了域名的信息
gethostbyaddr(): 可以將一個32位的IP地址(C0A80001)轉換為結構指針. 這兩個函數失敗時返回NULL 且設置h_errno錯誤變量,調用h_strerror()可以得到詳細的 出錯信息
3.3 字符串的IP和32位的IP轉換.
在網絡上面我們用的IP都是數字加點(192.168.0.1)構成的, 而在struct in_addr結構中 用的是32位的IP, 我們上面那個32位IP(C0A80001)是的192.168.0.1 為了轉換我們可以 使用下面兩個函數
在網絡上面我們用的IP都是數字加點(192.168.0.1)構成的, 而在struct in_addr結構中 用的是32位的IP, 我們上面那個32位IP(C0A80001)是的192.168.0.1 為了轉換我們可以 使用下面兩個函數
int inet_aton(const char *cp,struct in_addr *inp)
char *inet_ntoa(struct in_addr in)
函數裏面 a 代表 ascii, n 代表network. 第一個函數表示將a.b.c.d的IP轉換為32位的IP,存儲在 inp指針裏面.第二個是將32位IP轉換為a.b.c.d的格式.
3.4 服務信息函數
在網絡程序裏面我們有時候需要知道端口.IP和服務信息.這個時候我們可以使用以下幾 個函數
int getsockname(int sockfd,struct sockaddr *localaddr,int *addrlen)
int getpeername(int sockfd,struct sockaddr *peeraddr, int *addrlen)
struct servent *getservbyname(const char *servname,const char *protoname)
struct servent *getservbyport(int port,const char *protoname)
int getpeername(int sockfd,struct sockaddr *peeraddr, int *addrlen)
struct servent *getservbyname(const char *servname,const char *protoname)
struct servent *getservbyport(int port,const char *protoname)
struct servent {
char *s_name; /* 正式服務名 */ char **s_aliases; /* 別名列表 */ int s_port; /* 端口號 */ char *s_proto; /* 使用的協議 */ };
char *s_name; /* 正式服務名 */ char **s_aliases; /* 別名列表 */ int s_port; /* 端口號 */ char *s_proto; /* 使用的協議 */ };
一般我們很少用這幾個函數.對應Client,當我們要得到連接的端口號時在connect調用成 功後使用可得到 系統分配的端口號.對於Server,我們用INADDR_ANY填充後,為了得到連 接的IP我們可以在accept調用成功後 使用而得到IP地址. 在網絡上有許多的默認端口和服務,比如端口21對ftp80對應WWW.為了得到指定的端口號 的服務 我們可以調用第四個函數,相反為了得到端口號可以調用第三個函數.
3.5 一個例子
#include <netdb.h>;
#include <stdio.h>;
#include <stdlib.h>;
#include <sys/socket.h>;
#include <netinet/in.h>;
int main(int argc ,char **argv)
{
struct sockaddr_in addr; struct hostent *host; char **alias; if(argc<2) { fprintf(stderr,"Usage:%s hostname|ip..\n\a",argv[0]); exit(1); } argv++; for(;*argv!=NULL;argv++) { /* 這裏我們假設是IP*/
if(inet_aton(*argv,&addr.sin_addr)!=0) {
host=gethostbyaddr((char *)&addr.sin_addr,4,AF_INET);
printf("Address information of Ip %s\n",*argv);
}else {
/* 失敗,難道是域名?*/
host=gethostbyname(*argv);
printf("Address information of host %s\n",*argv);
}
if(host==NULL) {
/* 都不是 ,算了不找了*/
fprintf(stderr,"No address information of %s\n",*argv);
continue;
}
printf("Official host name %s\n",host->;h_name);
printf("Name aliases:");
for(alias=host->;h_aliases;*alias!=NULL;alias++)
printf("%s ,",*alias);
printf("\nIp address:");
for(alias=host->;h_addr_list;*alias!=NULL;alias++)
printf("%s ,",inet_ntoa(*(struct in_addr *)(*alias))); }
}
在這個例子裏面,為了判斷用戶輸入的是IP還是域名我們調用了兩個函數,第一次我們假 設輸入的是IP所以調用inet_aton, 失敗的時候,再調用gethostbyname而得到信息.
}
在這個例子裏面,為了判斷用戶輸入的是IP還是域名我們調用了兩個函數,第一次我們假 設輸入的是IP所以調用inet_aton, 失敗的時候,再調用gethostbyname而得到信息.
No comments:
Post a Comment