网络编程基础概念

1.网络编程的基本概念
    (1)IP地址
        IP地址的作用是标识网络中的一台计算机,每一台计算机都有一个IP地址。在程序中,通过IP地址来访问一台计算机。IP地址具有统一的格式,IP地址是32位长度的二进制数值,存储空间是4个字节。
    (2)端口
        所谓端口,是计算机中为了标识计算机中访问网络的不同程序的编号。每一个程序访问网络时,都会分配一个标识符。程序在访问网络或接受网络访问时,会用这个标识符表示网络数据属于这个程序。端口号是一个无符号16位整数,对应的十进制取值范围是0~65535。低于256的端口号是系统保留端口,主要用于标识系统进程。例如网站的www服务使用的端口号是80,FTP服务使用的端口号是21。端口号的作用是用于区分网络通信中主机上不同的网络应用程序。
    (3)域名
        用来代替IP地址以标识计算机的一种直观名称。例如百度的IP地址是202.108.22.43,百度的域名是 www.baidu.com
    (4)TCP与UDP
        TCP和UDP是两种不同的网络传输方式。两个不同计算机中的程序,使用IP地址和端口,使用一种约定的方法进行数据传输。TCP和UDP就是网络中的两种数据传输约定。主要的区别是进行数据传输时是否需要连接。
        TCP是一种面向连接的传输方式。计算机A先呼叫计算机B,计算机接受连接后发出确认信息,计算机A收到确认信息后发送信息,计算机B接收信息后发送完毕信息。这时再关闭数据连接。这种方式是可靠的,缺点是传输过程复杂,需要占用较多的网络资源。
        UDP是一种无面向连接的传输方式。使用UDP传送信息时,不建立连接,直接把信息发送到网络上,由网络完成信息的传送。信息完成以后也不发送确认信息。这种方式是不可靠的,但是有良好的传输效率。在对传输可靠性要求不高时,可以选择使用这种传输方式。(如果使用UDP协议进行数据通信,数据传输的可靠性由软件开发人员编程实现)
2.套接字
    (1)什么是套接字(socket=传输层协议+端口号+IP地址)
        网络中的两个应用程序相互通信时,可以使用TCP或者UDP方式传输数据。对于开发者来说,更关心的是传输的数据,而不是TCP或者UDP协议本身。因此,制定了一种用于网络传输数据的编程接口,成为套接字。区分不同应用程序进程间的网络通信和连接,主要使用三个参数:通信的目的IP地址,使用的传输层协议,使用的端口号。
    (2)套接字相关的数据结构
    (3)套接字类型
        套接字类型指的是在网络通信中不同的数据传输方式。常用的套接字类型有以下三种:
        流套接字:流套接字使用了面向连接的可靠的数据通信方式,即使用了TCP协议
        数据报套接字:数据报套接字使用了面向无连接的数据传输方式,即使用了UDP协议
        原始套接字:前面讲述的两种套接字是系统定义的,所有的信息都需要相应夫人方式进行封装。原始套接字是没有经过处理的IP数据包,可以根据自己程序的需要进行封装。如果要访问其他的协议,需要使用原始套接字来构造相应的协议。
3.域名与IP地址
    在TCP/IP网络中,通信双方的主机必须知道彼此的IP地址方可进行通信,如果给出主机的域名,在开始正常的通信前必须把域名转换成IP地址。这个域名到IP地址的转换过程称为域名解析
    (1)用域名获得主机的IP地址
    在使用域名访问网络时,需要将这个域名转换车成相应的IP地址。
    用域名返回IP地址的函数是gethostbyname,函数的定义如下所示:
    struct hostent* gethostbyname(const char name);
    在参数列表中,name是一个表示域名的字符串。函数会把这个域名转换成主机地址结构体返回。
    结构体hostent的定义如下:
    struct hostent
    {
        char *h_name;     //正式的主机名称
        char **h_aliases;    //主机的别名
        int h_addrtype;       //主机名的类型
        int h_length;        //地址的长度
        char **h_addr_list;    //从域名服务器取得的主机的地址
    }
    可能返回的错误信息如下所示:
            HOST_NOT_FOUND:主机没有找到
            NO_ADDTRSS or NO_DATA:没有ip地址或没有数据
            NO_RECOVERY:域名服务器发生错误
            TRY_AGAIN:请稍后再试
(2)用IP地址返回域名
    用一个IP地址可以查询到这个IP地址的域名,需要使用的函数是gethostbyaddr,定义如下所示:
    struct hostent* gethostbyaddr(const void *addr,socklen_t len,int type)
    在参数列表中addr是一个保存了IP地址的字符串,len是这个IP地址的长度,type的值一般是AF_INET。函数的返回值是hostent类型的指针。如果转换失败,则返回NULL指针
4.网络协议
所谓网络协议,是指不同的计算机,不同的操作系统,在进行网络通信时的统一约定。在编程中如何获取协议信息
(1)由协议名取得协议数据
如TCP,UPD等,是协议的名称。在编程时,需要用这些协议名称取得这些协议的数据。函数getprotobyname的作用是按名称取得一个协议的数据。getprotobyname函数定义如下:
struct protoent* getprotobyname(char *name);
name是一个表示协议名称的字符串。返回值是一个protoent类型的结构体指针。结构体protoent的定义如下:
struct protoent
{
char *p_name; //协议的名称
char **p_aliases;//协议的别名
int p_proto;//协议的序号
}
(2)用协议编号取得协议信息
知道了一个协议的编号,可以用getprotobynumber函数来取得这个协议的信息。这个函数的使用方法如下所示:
struct protoent* getprotobynumber(int proto);
在参数列表中,proto是一个协议的编号。函数会返回一个protoent类型的结构体指针
(3)取得系统支持的所有协议
函数getprotoent的作用是取得系统中支持的所有协议。getprotoent函数定义如下:
struct protoent* getprotoent(void);
这个函数没有参数,每次调用时,依次返回一个系统支持的协议,返回一个struct protoent结构体指针,到达末尾时会返回NULL指针。系统中支持的协议类型,记录在/etc/protocols文件中。
5.网络服务
所谓网络服务,是指网络上的计算机通过运行程序,为其他计算机提供信息或运算的功能。例如打开一个网页,是访问了网站服务器上的服务,从服务器上下载下来了网页文件。
(1)取得系统支持的网络服务
函数getservent的作用是取得系统所支持的服务。getservent函数的定义如下所示:
struct servent* getservent(void);
这个函数没有参数,返回一个servent类型的结构体指针。servent类型的定义如下所示:
struct servent
{
char *s_name; //服务名称
char **s_aliases; //服务可能的别名
int s_port; //服务可能的端口号
char *s_proto; //服务使用的协议
}
每次调用这个函数时,会返回一个系统支持的服务。如果已经到达最后一个,则返回NULL。系统中支持的服务,放在/etc/services文件中。
(2)用名称取得系统所支持的服务。
函数getservbyname可以用一个服务的名称取得服务。getservbyname的定义如下:
struct servent* getservbyname(char *name,char *proto);
在参数列表中,name是服务的名称,proto是该服务使用的协议。函数getservent可以查出参数所对应的系统服务,返回一个servent指针。如果没有查询到这个服务,会返回NULL指针
(3)用 端口号取得服务名称
函数getservbyport可以从一个端口号取得服务的信息。函数getservbyport的定义如下所示:
struct servent* getservbyport(int port,char *proto);
在参数的列表中,port是一个端口的编号。需要注意的是,这个端口号需要用htons()进行转换。proto是一个用来表示协议的字符串。这个函数会返回这个端口服务的servent类型的指针。
6.网络地址的交换
网络IP地址本是用32位二进制数表示的,为了记忆方便,可以用点分十进制数来表示IP地址。网络传输和计算机内部的字符存储的方式是不同的,需要用相关函数将端口号进行转换。、
(1)将网络地址转换成整型
函数inet_addr可以将一个网络IP地址转换成一个十进制长整型数。inet_addr函数的定义如下:
long inet_addr(char *cp);
函数的参数cp是一个表示IP地址的字符串。函数会将这个IP地址转换成一个长整型数。使用这个函数之前,需要在程序中包含头文件:sys/socket.h netinet/in.h arpa/inet.h
(2)将长整型地址转换成网络地址
函数inet_ntoa可以将整型数地址转换成点分十进制数网络地址。函数inet_ntoa定义如下:
char * inet_ntoa(struct in_addr in);
函数的参数in是一个in_addr类型的结构体,这个结构体的定义如下:
struct in_addr
{
uint32_t s_addr;
}
结构体中只有一个成员,s_addr是一个长整型数,用来存储一个长整型数的IP地址。函数inet_ntoa会把这个长整型数转换成一个字符串返回。使用这个函数之前,需要包含以下头文件:sys/socket.h netinet/in.h arap/inet.h
(3) 主机字符顺序与网络字符顺序的转换
计算机中的字符与网络中的字符存储顺序是不同的。计算机中的整型数与网络中的整型数进行交换时,需要用相关的函数进行转换。如果计算机中的长整型地址转换成网络字符顺序的整型地址,使用htonl函数。这些函数如下所示:
uint32_t htonl(uint32_t hostlong);
uint16_t htonl(uint16_t hostlong);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohl(uint16_t netlong);
以上的参数都是需要转换的整型数,函数把这些整型数转换以后返回。使用这些函数以前,需要在程序前包含arpa/inet.h
7.错误处理
(1)herror函数显示错误
函数herror可以显示上一个网络函数发生的错误。函数herror的定义如下:
void herror(const char *s);
这个函数的参数是一个字符串,调用这个函数时,会先输出这个字符串,然后直接输出错误信息。输出的错误信息是上一个网络相关的函数发生的错误。使用这个函数时,需要在程序最前面包含netdb.h文件
(2)捕获错误编号
在网络程序中,可以使用 extern int h_errno;捕获发生错误的编号。用hstrerror函数来输出这个错误信息。这个函数的定义如下;
char* hstrerror(int err);
这个函数的编号是已经捕获的错误信息的编号,函数会返回这个编号所对应的错误信息。在使用这个函数时,需要在程序最前面包含netdb.h文件                       


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值