读书人

sendto和recvfrom的有关问题

发布时间: 2012-06-16 20:34:32 作者: rapoo

sendto和recvfrom的问题
问题如下:
自己先填充了一个ICMP数据包的缓冲区,然后通过sendto发送,接着用recvfrom准备接收返回的信息,为什么recvfrom会一直挂起收不到数据呢?
socket采用下面函数构造:
socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

[解决办法]
这就太难说了, 信息太少了。
[解决办法]
网络编程初期的问题基本都是自己实现上的小bug,莫名其妙的

写多了自然就不出了


[解决办法]
下个UNIX网络编程看一下原始套接字章节的ICMP示例吧,网上的个人代码很难信赖。
[解决办法]
给个例子吧:

C/C++ code
#include "stdio.h"#include "Winsock2.h"#pragma comment( lib, "ws2_32.lib" ) //;typedef struct IpHeader{    unsigned char Version_HLen;    unsigned char TOS;    unsigned short Length;    unsigned short Ident;    unsigned short Flags_Offset;    unsigned char TTL;    unsigned char Protocol;    unsigned short Checksum;    unsigned int SourceAddr;    unsigned int DestinationAddr;} Ip_Header;typedef struct IcmpHeader{    BYTE Type;    BYTE Code;    USHORT Checksum;    USHORT ID;    USHORT Sequence;} Icmp_Header;USHORT checksum(USHORT *buff, int size){    unsigned long cksum = 0;    while (size > 1)    {        cksum +=  *buff++;        size -= sizeof(USHORT);    }    if (size)    {        cksum += *(UCHAR*)(buff);    }    cksum = (cksum >> 16) + (cksum &0xffff);    cksum += (cksum >> 16);    return (USHORT)(~cksum);}int main(int argc, char *argv[]){    WSADATA wsaData;    sockaddr_in DestAddr;    Ip_Header *ip;    Icmp_Header *icmp;    Icmp_Header *SendIcmp;    int Timeout = 1000;    //char DestIpAddr[100] = "192.168.1.3";   // char IcmpBuffer[8] = "";//too small    char IcmpBuffer[32] = "";    SOCKET IcmpSocket;    char RecvBuffer[1024];    sockaddr_in addr;    int Len = sizeof(addr);    int Result;    struct hostent * hp;    if (argc !=2 ) {//rendb        printf("Please input the dest!\n");        return 0;    }    if ((Result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)    {        printf("WSAStartup failed with error %d\n", Result);        return 0;    }    hp = gethostbyname(argv[1]);//rendb    if(hp==NULL){        printf("gethostbyname error %d!\n",WSAGetLastError());        return -1;          }    IcmpSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);    if (IcmpSocket == INVALID_SOCKET)    {        printf("socket failed with error %d\n", WSAGetLastError());        return 0;    }    Result = setsockopt(IcmpSocket, SOL_SOCKET, SO_RCVTIMEO, (char*) &Timeout, sizeof(Timeout));    if (Result == SOCKET_ERROR)    {        printf("setsockopt failed with error %d \n", WSAGetLastError());        return 0;    }    memset(&DestAddr, 0, sizeof(DestAddr));   // DestAddr.sin_addr.s_addr = inet_addr(DestIpAddr);    memcpy(&(DestAddr.sin_addr),hp->h_addr,hp->h_length);//rendb    DestAddr.sin_port = htons(0);    DestAddr.sin_family = AF_INET;    SendIcmp = (Icmp_Header*)IcmpBuffer;    SendIcmp->Type = 8;    SendIcmp->Code = 0;    SendIcmp->ID = (USHORT)GetCurrentProcessId();    SendIcmp->Sequence = htons(1);    SendIcmp->Checksum = 0;    SendIcmp->Checksum = checksum((USHORT*)IcmpBuffer, sizeof(IcmpBuffer));    printf("ping %s ...\n",inet_ntoa(DestAddr.sin_addr));    Result = sendto(IcmpSocket, IcmpBuffer, sizeof(IcmpBuffer), 0, (SOCKADDR*) &DestAddr, sizeof(DestAddr));    if (Result == SOCKET_ERROR)    {        printf("sendto failed with error %d \n", WSAGetLastError());        return 0;    }    Result = recvfrom(IcmpSocket, RecvBuffer, 1024, 0, (sockaddr*) &addr, &Len);    if (Result == SOCKET_ERROR)    {        if (WSAGetLastError() != WSAETIMEDOUT)        {            printf("recvfrom failed with error %d \n", WSAGetLastError());            return 0;        }        else        {            printf("Host %s may be down.\n", inet_ntoa(DestAddr.sin_addr));        }    }    if (Result < sizeof(Ip_Header) + sizeof(Icmp_Header))    {        printf("data error from %d\n", inet_ntoa(addr.sin_addr));    }    ip = (Ip_Header*)RecvBuffer;    if ((ip->SourceAddr == DestAddr.sin_addr.s_addr) && (ip->Protocol == IPPROTO_ICMP))    {        icmp = (Icmp_Header*)(RecvBuffer + sizeof(Ip_Header));        if (icmp->Type != 0)        {            printf("type error %d ", icmp->Type);            return 0;        }        if (icmp->ID != GetCurrentProcessId())        {            printf("id error %d\n", icmp->ID);            return 0;        }        else if ((icmp->Type == 0) && (icmp->ID == GetCurrentProcessId()))        {            //printf("Host %s is up.\n", DestIpAddr);            printf("Host %s is up.\n", argv[1]);        }    }    if (closesocket(IcmpSocket) == SOCKET_ERROR)    {        printf("closesocket failed with error %d\n", WSAGetLastError());        return 0;    }    if (WSACleanup() == SOCKET_ERROR)    {        printf("WSACleanup failed with error %d\n", WSAGetLastError());        return 0;    }    return 1;} 

读书人网 >C++

热点推荐