网络编程基础入门级

转自:http://blog.csdn.net/ubuntulover/article/details/4460211?reload

1.字节序

#include<netinet/in.h>
定义函数 unsigned short int htons(unsigned short int hostshort);
函数说明 htons()用来将参数指定的16位hostshort转换成网络字符顺序
返回值 返回对应的网络字符顺序。

#include<netinet/in.h>
定义函数 unsigned long int htonl(unsigned long int hostlong);
函数说明 htonl()用来将参数指定的32位hostlong转换成网络字符顺序
返回值 返回对应的网络字符顺序。

---可用于将端口号(无符号或整型)转换成网络字符顺序。


#include<netinet/in.h>
定义函数 unsigned long int ntohl(unsigned long int netlong);
函数说明 ntohl()用来将参数指定的32位netlong转换成主机字符顺序。
返回值 返回对应的主机字符顺序。


#include<netinet/in.h>
定义函数 unsigned short int ntohs(unsigned short int netshort);
函数说明 ntohs()用来将参数指定的16位netshort转换成主机字符顺序。
返回值 返回对应的主机顺序。

2.地址格式

linux中使用in_addr表示一个IP地址,该结构定义如下:

 #include <netinet/in.h>

struct in_addr{
in_addr_t ;

}

linux中地址结构定义如下:

#include <netinet/in.h>

struct socketaddr_in {

sa_family_t sin_family;//16位的地址组

in_port_t sin_port;//端口号

struct in_addr sin_addr;//32位的IP地址

unsigned char sin_zero[8];//填充区

最后填充区的作用是保证socketaddr_in结构正好16个字节,这样使socketaddr_in结构可以和socketaddr地址结构随意转换。

socketaddr结构的定义如下 

#includes<netinet/in.h>

sruct socketaddr{

sa_family_t sa_family;//16位的地址组

char sa_data[14];//14字节的填充区

}

3.地址形式转换

linux提供了函数用于将IP地址在二进制和点分十进制之间进行转换。 

#include <netinet/in.h>

const char * inet_ntop(int domain,const void * restrict addr,char * restrict str,socklen_t size);

int inet_pton(int domain,const char * restrict str,void * restrict addr);

domain可以为AF_INET或AF_INET6.

str所指向的区域存储IP地址的点分十进制表示形式的字符串,参数size表示的是该区域的大小,以防止因为地址格式不对导致的越界访问。因为IP地址的字符串形式包含四个“.”和一个“/0”结束符,所以存储该字符串的缓冲区最大应为3个字符数字*4+3个字符“.“+‘/0’共16个字节。

inet_ntop函数将二进制形式转换为字符串形式的地址。

inet_pton函数是inet_ntop的逆运算,该函数将字符串形式的地址转换为二进制形式的地址。 

范例:

//addr.c

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>

int main()
{
char addr_p[16];//ip地址的点分十进制形式
struct in_addr addr_in;//ip地址的二进制形式

if(inet_pton(AF_INET,"192.168.11.6",&addr_in)!=1){//地址由字符串转换为二进制形式
perror("fail to convert");
exit(1);
}
printf("address:%x/n",addr_in);

if(inet_ntop(AF_INET,&addr_n,addr_p,sizeof(addr_p))!=1){//地址由二进制转换为字符串形式
perror("fial to convert");
exit(1);
}

printf("address:%s/n",addr_p);

return 0;

4.获得主机信息

一台主机有许多和网络有关的信息,例如主机名名称,IP地址等。linux使用如下函数得到这些信息。 

#include <netdb.h>

struct hostent* gethostent(); 

该函数从系统的/etc/hosts文件中读取主机相关信息,并将其内容存储在系统中的一个静态缓冲区中,返回该缓冲区的首地址。 

#include <netdb.h> 

struct hostent{

char * h_name;//正式主机名,只有一个

char ** h_aliases;//主机别名列表,可能有很多个,保存在一个二维数组中

int h_addrtype;//IP地址类型

int h_length;//IP地址长度

cha ** h_addr_list;//IP地址列表,h_addr_list[0]为主机的IP地址

};

范例:

下例输出主机名和起别名。 

//gethostinfo.c

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>

#define NET_ADDR 16 //16个字节,用于存放点分十进制ip地址的字符串

int main()
{
struct hostent * host;//用于存放主机信息
char addr_p[NET_ADDR];
int i;

if((host=gethostent())==NULL){//获得主机信息
perror("fail to get host's information/n");
exit(1);
}

printf("%s/n",host->h_hame);//打印主机名

for(i=0;host->h_aliases[i]!=NULL;i++){//打印主机别名
printf("%s/n",host->h_aliases[i]);
}

if(host->h_addrtype==AF_INET)//打印地址类型
printf("af_inet/n");
else
printf("unix_inet/n");

printf("%d/n",host->h_length);//打印地址长度

for(i=0;host->h_addr_list[i]!=NULL;i++)//打印主机ip地址
printf("%s/n",inet_ntop(host->h_addrtype,host->h_addr_list[i],addr_p,NET_ADDR));

return 0;
}

5.地址映射

linux环境下提供了一个函数,根据用户指定的服务器域名和服务名称得到服务器的IP地址和端口号。并将其填写到一个sockaddr_in地址结构中。该函数内部访问量DNS服务器。 

#include <sys/socket.h>

#include <netdb.h> 

int getaddrinfo(const char * restrict host,const char * restrict  service,const struct addrinfo * restrict hint ,struct addrinfo ** restrict res); 

该函数的前两个参数分别表示需要访问的主机名和服务的名称(这两个名称要都已经在DNS服务器中注册)。第三个参数表示一个过滤地址模板,通常情况下不过滤任何IP地址,因此置为NULL。

第四个参数表示一个地址信息结构的列表。该列表列出了所有可用的符合条件的地址结构,用户可以从中任选一个作为通信的地址。

原文地址:https://www.cnblogs.com/siliconvalley/p/3112507.html