【问题标题】:Assigning String to Hostent in C在 C 中将字符串分配给 Hostent
【发布时间】:2014-09-01 02:16:08
【问题描述】:

我正在编写一些代码来查找 Web 服务器。它在 C 中。

我有这个

sprintf(pre_ip, "%d.%d.%d.%d", num1, num2, num3, num4);

num1-4 是一个类似 1.1.1.1 的 ip。这部分有效..

he = gethostbyname(pre_ip);

这应该将struct hostent *he; 分配给ip..

但这不起作用..

server_info.sin_addr = *((struct in_addr *)he->h_addr);
connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr));

这是整个代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//lol220
int main(int argc, char *argv[])
{
    struct sockaddr_in server_info;
    struct hostent *he;
    int socket_fd,num;
    char buffer[1024];

    char buff[1024];

    if (argc != 1) {
        fprintf(stderr, "Usage: client hostname\n");
        exit(1);
    }

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
        fprintf(stderr, "Socket Failure!!\n");
        exit(1);
    }

    memset(&server_info, 0, sizeof(server_info));
    server_info.sin_family = AF_INET;
    server_info.sin_port = htons(80);

//-------------------------------looooop------------------------
int num1 = 1;
int num2 = 1;
int num3 = 1;
int num4 = 1;
int done = 1;
char ip;
char pre_ip[256];
while(done){
        if(num4 == 256){
        num4 = 1;
        num3++;
        }
        if(num3 == 256){
        num3 = 1;
        num2++;
        }
        if(num2 == 256){
        num2 = 1;
        num1++;
        }
        if(num1 == 255 && num2 == 255 && num3 == 255 && num4 == 255){
        done = 0;
        }
        // MOST LIKELY NON WORKING PART 
        sprintf(pre_ip, "%d.%d.%d.%d", num1, num2, num3, num4);
        printf("%s\n", pre_ip);
        he = gethostbyname(pre_ip);
        server_info.sin_addr = *((struct in_addr *)he->h_addr);
            if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) {
                printf("Could not connect to %s", he);
            }
            else{
                printf("Could connect to %s", he);
            }
        // MOST LIKELY NON WORKING PART 

num4++;
}
return 0;
}

它编译得很好。

打印“1.1.1.1”,然后显示“无法连接到 8T1.1.1.2”,这意味着 he == "8T1.1.1.2

【问题讨论】:

  • A hostent* 不是 char*,因此您无法使用 %s 打印 hostent 的内容。

标签: c sockets compiler-errors webserver


【解决方案1】:

当你在这一行打印ip时:

printf("Could not connect to %s", he);

您将 struct hostent 转换为 char *,这会导致 ip 之前的奇数字符。其实用ip直接连接服务器就可以了,不用gethostbyname。如果你真的想试试这个功能,就这样吧:

bzero(&server_info, sizeof(server_info));
const char *ip = inet_ntoa(server_info.sin_addr);
...
printf("Could not connect to %s", ip);

【讨论】:

  • 或者,不要调用inet_ntoa(),而是使用已经预先格式化为IP地址的pre_ip缓冲区
  • 确实如此。也许op只是从某个地方复制了一些代码并尝试了它:)
  • 请考虑not using bzero()bzero() 函数在 POSIX.1-2001 中已弃用,并在 POSIX.1-2008 中删除。请改用memset()
【解决方案2】:

试试类似的方法:

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

int main(int argc, char *argv[])
{
    struct sockaddr_in server_info;
    int socket_fd;

    if (argc != 1) {
        fprintf(stderr, "Usage: client hostname\n");
        exit(1);
    }

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
        fprintf(stderr, "Socket Failure!!\n");
        exit(1);
    } 

    memset(&server_info, 0, sizeof(server_info));
    server_info.sin_family = AF_INET;
    server_info.sin_port = htons(80);

    for (uint32_t ip = 0x01010101; ip != 0xFFFFFFFF; ++ip) {
        server_info.sin_addr.s_addr = htonl(ip);
        printf("Connect to %s: ", inet_ntoa(server_info.sin_addr));
        if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(server_info)) == -1) {
            printf("Failed\n");
        }
        else {
            printf("Success\n");
            close(socket_fd);
            if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                fprintf(stderr, "Socket Failure!!\n");
                exit(1);
            } 
        }
    }
    return 0;
}

【讨论】:

  • 你为什么要检查 argc?
  • 因为是在原代码里,所以我把它留在了,假设发帖人以后会用到。我唯一改变的是连接循环。
猜你喜欢
  • 2015-09-15
  • 2020-07-23
  • 2011-10-15
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多