批量查询IP引起的警示

写了一阵子C++,再写C就不怎么顺手了,写成了“高级集成语言”,再写“低级集成语言”,发现很多东西都不顺手,就拿这次批量查询IP来说吧,对于fgets读取获得的buf,C++中似乎不用管这个指针变量char *所指地址的大小,而C语言就不同了,直接指定char *会发生core dump,必须指定char的大小,另外,我测试平台可能也有很大关系,我在windows下的cygwin平台没有错误,但是在linux下发生错误,freebsd下却因为inet的问题导致错误,很稀奇,在cygwin下代码如下:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

#define DOMAINLENGTH 100

int main (int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("usage: %s <infile> <outfile>\n", argv[0]);
        return 0;
    }
    struct in_addr addr;
    struct hostent * domain;
    uint address = 0;
    char *dom;
    char *ipaddress;
    char *output;
    FILE *fp;
    FILE *op;
    if ((fp = fopen(argv[1], "r")) == NULL)
    {
        perror("Can't read the file!");
        exit(1);
    }
    if ((op = fopen(argv[2], "w")) == NULL)
    {
        perror("Can't write the file!");
        exit(1);
    }
    int i;
    while (fgets(dom, DOMAINLENGTH, fp))
    {
       
        int domLen = strlen(dom);
        for (i = 0; i < domLen; i ++)
        {
            if (dom[i] == '\r' || dom[i] == '\n') dom[i] = '\0';
        }
        if (*dom == 0 || strlen(dom) < 5) continue;
        if (strstr(dom, ":") || strstr(dom, "/"))
        {
            char *httptype = strtok(dom, ":");
            char *host = strtok(NULL, " ");
            if (strcmp(httptype, "http") == 0 || strcmp(httptype, "https") == 0 || strcmp(httptype, "ftp") == 0)
            {
                if (strstr(host, ":"))
                {
                    if ((httptype = strtok(host, ":")) != NULL)
                    {
                        host = strtok(NULL, " ");
                        sprintf(host, "%s", httptype);
                    }
                }
                if (strstr(host, "//"))
                {
                   
                    char *slashs = strtok(host, "//");
                    sprintf(host, "%s", slashs);
                }
                if (strstr(host, "/"))
                {
                    char *slash = strtok(host, "/");
                    sprintf(host, "%s", slash);
                }
                sprintf(dom, "%s", host);
            }
            else
            {
                if (strstr(httptype, "/"))
                {
                    char *slash = strtok(httptype, "/");
                    sprintf(httptype, "%s", slash);
                }
                sprintf(dom, "%s", httptype);
            }
        }
        if (isalpha(*dom))
        {
            domain = gethostbyname(dom);
            if (domain != NULL)
             {
                address = ((uint*)domain->h_addr_list[0])[0];
                if ( (address & 0xffff) == 0x0a0a ) address= ((uint*)domain->h_addr_list[0])[1];
             }
        }
        else
        {
            address = inet_addr(dom);
        }
        addr.s_addr = address;
        ipaddress = inet_ntoa(addr);
        sprintf(output, "%s\t%s\n", dom, ipaddress);
        if (fputs( output, op ) == EOF)
        {
            perror("Write error!");
            exit(1);
        }
    }   
    fclose(fp);
    fclose(op);
    return 0;
}

在linux正确运行代码如下:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#define DOMAINLENGTH 100

int main (int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("usage: %s <infile> <outfile>\n", argv[0]);
        return 0;
    }
    struct in_addr addr;
    struct hostent * domain;
    uint address = 0;
    char dom[DOMAINLENGTH];
    char output[DOMAINLENGTH+16];
    char *ipaddress;
    FILE *fp;
    FILE *op;
    if ((fp = fopen(argv[1], "r")) == NULL)
    {
        perror("Can't read the file!");
        exit(1);
    }
    if ((op = fopen(argv[2], "w")) == NULL)
    {
        perror("Can't write the file!");
        exit(1);
    }
    int i;
    while (fgets(dom, DOMAINLENGTH, fp) != NULL)
    {
        int domLen = strlen(dom);
        for (i = 0; i < domLen; i ++)
        {
            if (dom[i] == '\r' || dom[i] == '\n') dom[i] = '\0';
        }
        if (*dom == 0 || strlen(dom) < 5) continue;
        if (strstr(dom, ":") || strstr(dom, "/"))
        {
            char *httptype = strtok(dom, ":");
            char *host = strtok(NULL, " ");
            if (strcmp(httptype, "http") == 0 || strcmp(httptype, "https") == 0 || strcmp(httptype, "ftp") == 0)
            {
                if (strstr(host, ":"))
                {
                    if ((httptype = strtok(host, ":")) != NULL)
                    {
                        host = strtok(NULL, " ");
                        sprintf(host, "%s", httptype);
                    }
                }
                if (strstr(host, "//"))
                {

                    char *slashs = strtok(host, "//");
                    sprintf(host, "%s", slashs);
                }
                if (strstr(host, "/"))
                {
                    char *slash = strtok(host, "/");
                    sprintf(host, "%s", slash);
                }
                sprintf(dom, "%s", host);
            }
            else
            {
                if (strstr(httptype, "/"))
                {
                    char *slash = strtok(httptype, "/");
                    sprintf(httptype, "%s", slash);
                }
                sprintf(dom, "%s", httptype);
            }
        }
        if (isalpha(*dom))
        {
            domain = gethostbyname(dom);
            if (domain != NULL)
             {
                    address = ((uint*)domain->h_addr_list[0])[0];
                    if ( (address & 0xffff) == 0x0a0a ) address= ((uint*)domain->h_addr_list[0])[1];
            }
        }
        else
        {
            address = inet_addr(dom);
        }
        addr.s_addr = address;
        ipaddress = inet_ntoa(addr);
        sprintf(output, "%s\t%s\n", dom, ipaddress);
        printf("%s", output);
        if (fputs( output, op ) == EOF)
        {
            perror("Write error!");
            exit(1);
        }
    }
    fclose(fp);
    fclose(op);
    return 0;
}

freebsd下正确运行与linux运行不一样就是结构申明没有那么自由,linux下可以任意处申明,而freebsd必须函数开头申明,程序如下:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define DOMAINLENGTH 100

int main (int argc, char *argv[])
{
    struct in_addr addr;
    struct hostent * domain;
    uint address = 0;
    char dom[DOMAINLENGTH];
    char output[DOMAINLENGTH+16];
    char *ipaddress;
    FILE *fp;
    FILE *op;
    int i = 0;
    if (argc != 3)
    {
        printf("usage: %s <infile> <outfile>\n", argv[0]);
        return 0;
    }
    if ((fp = fopen(argv[1], "r")) == NULL)
    {
        perror("Can't read the file!");
        exit(1);
    }
    if ((op = fopen(argv[2], "w")) == NULL)
    {
        perror("Can't write the file!");
        exit(1);
    }
    while (fgets(dom, DOMAINLENGTH, fp) != NULL)
    {
        int domLen = strlen(dom);
        for (i = 0; i < domLen; i ++)
        {
            if (dom[i] == '\r' || dom[i] == '\n') dom[i] = '\0';
        }
        if (*dom == 0 || strlen(dom) < 5) continue;
        if (strstr(dom, ":") || strstr(dom, "/"))
        {
            char *httptype = strtok(dom, ":");
            char *host = strtok(NULL, " ");
            if (strcmp(httptype, "http") == 0 || strcmp(httptype, "https") == 0 || strcmp(httptype, "ftp") == 0)
            {
                if (strstr(host, ":"))
                {
                    if ((httptype = strtok(host, ":")) != NULL)
                    {
                        host = strtok(NULL, " ");
                        sprintf(host, "%s", httptype);
                    }
                }
                if (strstr(host, "//"))
                {

                    char *slashs = strtok(host, "//");
                    sprintf(host, "%s", slashs);
                }
                if (strstr(host, "/"))
                {
                    char *slash = strtok(host, "/");
                    sprintf(host, "%s", slash);
                }
                sprintf(dom, "%s", host);
            }
            else
            {
                if (strstr(httptype, "/"))
                {
                    char *slash = strtok(httptype, "/");
                    sprintf(httptype, "%s", slash);
                }
                sprintf(dom, "%s", httptype);
            }
        }
        if (isalpha(*dom))
        {
             domain = gethostbyname(dom);
            if (domain != NULL)
             {
                    address = ((uint*)domain->h_addr_list[0])[0];
                    if ( (address & 0xffff) == 0x0a0a ) address= ((uint*)domain->h_addr_list[0])[1];
             }
        }
        else
        {
            address = inet_addr(dom);
        }
        addr.s_addr = address;
        ipaddress = inet_ntoa(addr);
        sprintf(output, "%s\t%s\n", dom, ipaddress);
        printf("%s", output);
        if (fputs( output, op ) == EOF)
        {
            perror("Write error!");
            exit(1);
        }
    }
    fclose(fp);
    fclose(op);
    return 0;
}

都是使用的标准ASCII C函数,怎么会那么大的差别,现总结经验如下,freebsd是比较好的规范程式代码的方案,他所正确运行的代码在其他平台下都能正确的运行,而cygwin环境下的最为自由,当然,以语言比较而言,刚才上述代码在C++里面都可以正确运行,说明C++容错性或者扩展性比C强。

Categories

| | 评论(0)

Post a comment

关于此日记

此日记由Cnangel发表于2007年10月28日 10:45

此Blog上的上一篇日记关于DBI的一点忽略的东西

此Blog上的下一篇日记推荐一个集合开源PHP的网站

主索引归档页可以看到最新的日记和所有日记。

2008年10月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Powered by Movable Type 4.21-zh-cn