《UNIX 网络编程》 第三章课后习题第三题

试写一个名为inet_pton_loose的函数,它能处理如下情形:如果地址族为AF_INET且inet_pton返回0,那就调用inet_aton看是否成功;类似地,如果地址族为AF_INET6且inet_pton返回0,那么就调用inet_aton看是否成功,若成功返回其IPv4映射的IPv6地址。

#include <stdio.h>  
#include <stdlib.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <string.h>  


/** 
具体的转换过程,不做详细注释,有更好的实现方式 
**/   
int  
inet_pton_loose(int family,const char *strptr,void *addrptr)  
{     
    int i = 0;    

    if(inet_pton(family,strptr,addrptr) == 0){  

        struct in_addr  v4addr;  

        if(inet_aton(strptr,&v4addr)    == 1){  

            if(family == AF_INET){  

                memcpy(addrptr,(void *)&v4addr,sizeof(struct in_addr));   
                return 1;  
            }  

            if(family == AF_INET6){  

                struct in6_addr v6addr;  

                for(i=0;i<16;i++){  

                    if(i<10)  
                        v6addr.s6_addr[i] = 0;  
                    if(i >= 10 && i < 12)  
                        v6addr.s6_addr[i] = 0xf;  
                    if(i >= 12 )  
                        v6addr.s6_addr[i] = htonl(v4addr.s_addr)>>(16-i-1)*8;  

                }  
                memcpy(addrptr,(void *)&v6addr,sizeof(struct in6_addr));  
                return 1;                             
            }     
        }  
        return 0;  
    }         
    return 1;  
}  

/** 
获取输入,辨别是IPv4 还是IPv6 并做相应的处,理完成后输出用户的输入。没有添加错误处理。 
**/  
int  
main(int argc,char **argv)  
{  
    struct in_addr IPv4addr;  
    struct in6_addr IPv6addr;  

    const u_char *strptr;  
    const char *AddrFlag4 = "AF_INET";  
    const char *AddrFlag6 = "AF_INET6";  

    if(strcmp(AddrFlag4,argv[1]) == 0){  

        if(inet_pton_loose(AF_INET,argv[2],(void *)&IPv4addr) == 1){  

            strptr = (u_char *)&IPv4addr;  
            printf("%s---%d.%d.%d.%d\n",argv[1],strptr[0],strptr[1],strptr[2],strptr[3]);  
            return 1;  
        }  

    }  

    if(strcmp(AddrFlag6,argv[1]) == 0){  

        if(inet_pton_loose(AF_INET6,argv[2],(void *)&IPv6addr)  == 1){  

            strptr = (u_char *)&IPv6addr;  
            printf("%s---%d%d:%d%d:%d%d:%d%d:%d%d:%x%x:%d.%d.%d.%d\n",argv[1],strptr[0],strptr[1],  
                strptr[2],strptr[3],strptr[4],strptr[5],strptr[6],strptr[7],strptr[8],strptr[9]  
                ,strptr[10],strptr[11],strptr[12],strptr[13],strptr[14],strptr[15]);  

            return 1;  
        }  
    }  

    return 1;  
}  
#include "unp.h"

in_addr_t inet_pton_loose(int family, const char *strptr,void *addrptr)

{

    struct in_addr *ap = (struct in_addr *)addrptr;

    int result = 0;

    if((family == AF_INET) && (inet_pton(family,strptr,addrptr) == 0))

    {

        printf("the net protocol is IPv4 str is %s\n",strptr);

        result = inet_aton(strptr,ap);

        printf("result is %d\n",result);

        if(result)

            return ap->s_addr;

        else 

            return 0;

    }

    else if ((family == AF_INET6) && (inet_pton(family,strptr,addrptr) == 0))

    {

        printf("the net protocol is IPv6\n");

        result = inet_aton(strptr,ap);

        printf("result is %d\n",result);

        if(result)

        {

            return ap->s_addr;

        }

        else 

            return 0;

    }

    return 0;

}

int main (int argc, char **argv)

{

    //if argv[1] is zero, means AF_INET type, 1 for AF_INET6 type

    char s[20];

    struct in_addr addr;

    in_addr_t addr_result = 0;

    if(argc < 2)

    {

        printf("usage: ./mytest <fa> <addr>\n");

        return 1;

    }

    bzero(&addr,sizeof(struct in_addr));

    memset(s,0,sizeof(s));

    strcpy(s,argv[2]);

    if(atoi(argv[1]) == 0)

    {

        printf("the net protocol is IPv4\n");

        addr_result = inet_pton_loose(AF_INET,s,(void *)&addr);

        printf("addr_result is %x\n",addr_result);

    }

    else if(atoi(argv[1]) == 1)

    {

        printf("the net protocol is IPv6\n");

        addr_result = inet_pton_loose(AF_INET6,s,(void *)&addr);

        printf("addr_result is %x\n",addr_result);

    }

    return 0;

    }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《UNIX网络编程(第三版)》是由W. Richard Stevens和Bill Fenner合著的一本经典著作。该书深入讲解了UNIX操作系统网络编程的相关知识和技巧,是学习UNIX网络编程的优秀资料。 这本书主要分为两部分,第一部分介绍了UNIX网络编程的基本概念和基础知识。作者从TCP/IP协议栈、套接字编程接口、进程间通信等基本概念入手,详细解析了UNIX网络编程的核心技术。此外,还介绍了UNIX操作系统网络编程的原理与实践,包括网络编程API、套接字选项、IO复用技术等。这部分内容全面详细,对于初学者来说很容易理解和上手。 第二部分则是实际应用方面的内容。作者通过具体的实例,深入探讨了UNIX网络编程在实际项目中的应用。包括网络连接、TCP和UDP服务器、多进程/多线程服务器、域名解析、广播和组播等。通过这些实例,读者可以更好地理解和运用UNIX网络编程的技术和方法。 《UNIX网络编程(第三版)》在内容上全面而深入,实用性强。这本书既适合初学者作为学习的入门教材,也适合有一定经验的开发人员作为手册和工具书。此外,该书的编写风格清晰简练,结构合理,配有大量实例和图示,有助于读者更好地理解和运用所学的知识。 总之,《UNIX网络编程(第三版)》是一本经典的UNIX网络编程指南,无论是对于初学者还是有经验的开发人员,都是一本不可多得的优秀参考书。阅读和学习该书的内容,不仅可以提升对UNIX网络编程的理解和应用水平,还能够为进一步深入学习和研究相关领域提供坚实的基础。 ### 回答2: 《UNIX网络编程 第三版》(英文版)是由W. Richard Stevens和Bill Fenner编著的一本网络编程方面的经典参考书籍。 该书深入讲解了UNIX操作系统下网络编程的各个方面,包括套接字编程、进程控制、线程编程、信号处理、I/O复用、套接字选项、多播、广播、多路复用器、非阻塞I/O、地址转换、名字和地址转换等等。此外,该书还介绍了UNIX系统的底层协议,如TCP/IP和UDP/IP,并详细解释了网络编程中的各种细节和技巧。 《UNIX网络编程 第三版》以其深入浅出的讲解风格和丰富的示例代码而闻名,每个章节都有大量的代码示例和案例,便于读者理解和实践。此外,书中还包含了大量的图表和图示,帮助读者更好地理解网络编程中的各个概念和过程。 此外,《UNIX网络编程 第三版》还包含了关于IPv6的内容,对IPv6进行了深入讲解和示例演示,使读者能够了解并应用最新的网络技术。 总之,这本书是一本非常权威和全面的UNIX网络编程参考书籍,不仅适合网络编程从业人员和学习者,也适用于正在进行网络编程项目的开发人员。无论是初学者还是有经验的专业人士,都可以从中获得不少的收获。如果你对UNIX网络编程感兴趣或需要进行相关开发,这本书是一本不可或缺的参考资料。 ### 回答3: 《UNIX网络编程 第三版》是由W. Richard Stevens和Bill Fenner共同编写的经典图书。这本书是Unix网络编程领域的权威和经典之作,被广泛认为是学习Unix系统编程网络编程的指南。 这本书首先介绍了Unix网络编程的基本概念和原理,包括套接字、地址族、TCP/IP协议等。然后,它详细介绍了Unix网络编程的各个方面,包括套接字编程、多进程和多线程编程、I/O多路复用、UDP编程、域名解析等。 书中采用了清晰易懂的语言,配合大量的示例代码和图表,帮助读者理解和掌握Unix网络编程的核心概念和技术。它不仅注重理论知识的介绍,还强调实际应用和问解决,为读者提供了大量实用的编程经验和技巧。 此外,第三版还新增了一些内容,如IPv6编程、高级I/O、Scoket选项、Socket超时、IP选项处理等,以适应当今互联网发展的需求。 总的来说,《UNIX网络编程 第三版》是Unix系统和网络编程领域的经典教材,不仅适合想要深入了解Unix网络编程的学生和开发人员,也是Unix系统管理员和网络工程师的必备参考书。它既具备理论性,又注重实践应用,可以帮助读者更好地理解和应用Unix网络编程技术,提高系统和网络的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值