Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
recvfrom错误_C - Fatal编程技术网

recvfrom错误

recvfrom错误,c,C,我尝试创建一个函数,将icmp数据包发送到另一台计算机,当另一台计算机发送回某个数据包时,该函数返回1,否则返回0。但是recvfrom函数返回一个错误:“errno:资源暂时不可用”。我在MacOSX上工作,所以我不包括来自linux内核的头文件。谁能帮帮我,因为我卡住了 #include "info.h" char *getip() { char buffer[256]; struct hostent *h; gethostname(buffer, 256);

我尝试创建一个函数,将icmp数据包发送到另一台计算机,当另一台计算机发送回某个数据包时,该函数返回1,否则返回0。但是recvfrom函数返回一个错误:“errno:资源暂时不可用”。我在MacOSX上工作,所以我不包括来自linux内核的头文件。谁能帮帮我,因为我卡住了

#include "info.h"


char *getip()
{
    char buffer[256];
    struct hostent *h;

    gethostname(buffer, 256);
    h = gethostbyname(buffer);

    return inet_ntoa(*(struct in_addr *)h->h_addr);

}


int host_alive(char *dst_addr, char *src_addr)
{
    struct ip *ippacket;
    struct ip *ip_reply;
    struct icmp *icmppacket;
    struct sockaddr_in connection;
    struct timeval tv;
    char *packet;
    char *buffer;
    int optval;
    int addrlen;
    int size;
    int sock = 0;

    packet = malloc(sizeof(struct ip) + sizeof(struct icmp));
    buffer = malloc(sizeof(struct ip) + sizeof(struct icmp));

    check(getuid() == 0, "Root priviliges are needed. Try: sudo ./bin/main");

    ippacket = (struct ip *) packet;
    icmppacket = (struct icmp *) (packet + sizeof(struct ip));

    ippacket->ip_hl = 5;
    ippacket->ip_v = 4;
    ippacket->ip_tos = 0;
    ippacket->ip_len = sizeof(struct ip) + sizeof(struct icmp);
    ippacket->ip_id = htons(random());
    ippacket->ip_ttl = 255;
    ippacket->ip_p = IPPROTO_ICMP;
    inet_aton(src_addr, &ippacket->ip_src);
    inet_aton(dst_addr, &ippacket->ip_dst);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    check((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1,\
          "Failed to create socket");

    check(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int)) != -1,\
          "Failed to set the option to the socket.");
    check(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(struct timeval)) != -1,\
          "Failed to set the option to the socket.");

    icmppacket->icmp_type = ICMP_ECHO;
    icmppacket->icmp_code = 0;
    icmppacket->icmp_id = 0;
    icmppacket->icmp_seq = 0;
    icmppacket->icmp_cksum = in_cksum((unsigned short *)icmppacket, sizeof(struct icmp));

    ippacket->ip_sum = in_cksum((unsigned short *)ippacket, sizeof(struct ip));

    connection.sin_family = AF_INET;
    connection.sin_addr.s_addr = inet_addr(dst_addr);

    sendto(sock, packet, ippacket->ip_len, 0, (struct sockaddr *)&connection,\
          sizeof(struct sockaddr));

    addrlen = sizeof(connection);
    check((size = recvfrom(sock, buffer, sizeof(struct ip) + sizeof(struct icmp), 0,\
      (struct sockaddr *)&connection, (socklen_t *)&addrlen)) != -1,\
      "Failed to receive a message.");

    printf("Received %d byte reply from %s:\n", size , dst_addr);
    ip_reply = (struct ip*) buffer;
    printf("ID: %d\n", ntohs(ip_reply->ip_id));
    printf("TTL: %d\n", ip_reply->ip_ttl);

    close(sock);

    free(packet);
    free(buffer);

    return 1;

  error:
    if (sock)
        close(sock);
    free(packet);
    free(buffer);
    return 0;
}


unsigned short in_cksum(unsigned short *addr, int len)
{
    int sum = 0;
    u_short answer = 0;
    u_short *w = addr;
    int nleft = len;

    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }

    if (nleft == 1) {
        *(u_char *) (&answer) = *(u_char *) w;
        sum += answer;
    }
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return (answer);
}

根据
recvfrom
的文档,如果您使用的是非阻塞调用,这是预期的:

如果套接字上没有可用的消息,则接收调用将等待消息到达,除非套接字是非阻塞的(请参见
fcntl(2)
),在这种情况下,返回值-1,并且外部变量- able errno设置为
EAGAIN
。receive calls通常返回任何可用的数据,直到请求的金额,而不是等待收到请求的全部金额;此行为受 插槽级别选项
SO_RCVLOWAT
SO_RCVTIMEO
getsockopt(2)
所述。 如果您想知道哪些值对应哪些错误,可以在
/usr/include/sys/errno.h
中查找
errno

如果要阻止此功能,可能需要设置
MSG_WAITALL
标志,该标志“请求操作阻止,直到完全满足请求”


通常,在低级UNIX套接字代码中,您会在该套接字上执行
选择
,以等待读取信号,然后调用
recvfrom
以在且仅当该信号触发时接收数据。您也可以在
EAGAIN上执行非阻塞接收,只需等待一小段时间,然后再试一次,尽管这样效率较低。

根据
recvfrom
的文档,如果您使用的是非阻塞调用,这是预期的:

如果套接字上没有可用的消息,则接收调用将等待消息到达,除非套接字是非阻塞的(请参见
fcntl(2)
),在这种情况下,返回值-1,并且外部变量- able errno设置为
EAGAIN
。receive calls通常返回任何可用的数据,直到请求的金额,而不是等待收到请求的全部金额;此行为受 插槽级别选项
SO_RCVLOWAT
SO_RCVTIMEO
getsockopt(2)
所述。 如果您想知道哪些值对应哪些错误,可以在
/usr/include/sys/errno.h
中查找
errno

如果要阻止此功能,可能需要设置
MSG_WAITALL
标志,该标志“请求操作阻止,直到完全满足请求”


通常,在低级UNIX套接字代码中,您会在该套接字上执行
选择
,以等待读取信号,然后调用
recvfrom
以在且仅当该信号触发时接收数据。您也可以执行非阻塞接收,并在
EAGAIN
上等待一小段时间,然后再试一次,尽管这样效率较低。

您得到的是哪种错误代码?
man recvfrom
末尾有一个可能的错误列表。资源暂时不可用我指的是编号,
Exxxx
代码。这是英文消息,调用该函数并不是预期的结果之一。是否可能是
EAGAIN
?我只收到以下信息:[错误](src/info.c:77:errno:Resource暂时不可用)无法接收消息。
info.h
的内容是什么?您收到了哪些errno代码?
man recvfrom
末尾有一个可能的错误列表。资源暂时不可用我指的是编号,
Exxxx
代码。这是英文消息,调用该函数并不是预期的结果之一。是否可能是
EAGAIN
?我只收到以下信息:[错误](src/info.c:77:errno:Resource暂时不可用)无法接收消息。
info.h
的内容是什么?谢谢,但该功能在IP地址下也不起作用,当您ping它时,它正在响应。但是,值得在此处仅为超时功能添加一个
select
调用。您的意思是,使用select捕捉信号,如果它捕捉到信号,则可以通过recvfrom返回数据。该信号的名称是什么?与其说它是一个信号,不如说它是一个“准备读取”指示器。我发现这确实很有帮助,但您可能知道另一个涉及此主题的参考资料。UNIX编程中的“信号”指的是类似于
SIGKILL
SIGINT
的处理级别信号。谢谢,但该函数也不能与IP地址一起工作,当您ping它时,它会响应。不过,值得在此处添加一个
select
调用,仅用于超时功能。您的意思是,使用select捕捉信号,如果它捕捉到信号,数据可以通过recvfrom返回。该信号的名称是什么?与其说它是一个信号,不如说它是一个“准备读取”指示器。我发现这确实很有帮助,但您可能知道另一个涉及此主题的参考资料。UNIX编程中的“信号”指类似于进程级信号的
SIGKILL
SIGINT