recvfrom ()总是返回-1

sillyou 2004-12-20 05:36:10

#define IP_RECORD_ROUTE 0x07
#define IP_OPTIONS 0x01

// ipheader struct...

#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 //Minimum 8-byte packet (header)

// icmp header struct

// IP option header use of socket with IP_OPTIONS

#define DEF_PACKET_SIZE 32 // default packet size
#define MAX_PACKET_SIZE 1024 // icmp header max length
#define MAX_IP_HDR_SIZE 60 // max ip header size w/options


BOOL bRecRoute;
int dataSize;
char *lpDest;


// function FillIcmpHeader()
// description
//
void FillIcmpHeader(char *icmp_data, int datasize)
{
IcmpHeader *icmp_hdr = NULL;
char *datapart = NULL;

icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->type = ICMP_ECHO;
icmp_hdr->code = 0;
icmp_hdr->ident = (unsigned short)GetCurrentProcessId();
icmp_hdr->checksum = 0;
icmp_hdr->seq = 0;

datapart = icmp_data + sizeof(IcmpHeader);
memset(datapart, 'E', datasize - sizeof(IcmpHeader));
}

// function CheckSum()
// description
//
USHORT CheckSum(USHORT *buffer, int datasize)
{
unsigned long cksum = 0;

while (datasize > 0)
{
cksum += *buffer++;
datasize -= sizeof(USHORT);
}

if (datasize != 0)
{
cksum += *(UCHAR*)buffer;
}

cksum = (cksum >> 16) + (cksum && 0xFFFF);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}

//...
//
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sockRaw = INVALID_SOCKET;
struct sockaddr_in dest,
local,
from;

int bread,
fromlen = sizeof(from),
timeout = 1000,
ret;

char *icmp_data = NULL,
*recv_buf = NULL;

unsigned int addr = 0;
USHORT seq_no = 0;
struct hostent *hp = NULL;
IpOptionHeader ipopt;

ValidateArgs(argc, argv);

if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("WSAStartup failed. %d\n", WSAGetLastError());
return -1;
}

if ((sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == INVALID_SOCKET)
//if ((sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed. %d\n", WSAGetLastError());
WSACleanup();
return -1;
}

if (bRecRoute)
{
memset((void*)&ipopt, 0, sizeof(ipopt));
ipopt.code = IP_RECORD_ROUTE;
ipopt.ptr = 4;
ipopt.len = 39;

ret = setsockopt(sockRaw, IPPROTO_IP, IP_OPTIONS, (char*)&ipopt, sizeof(ipopt));

if (ret == SOCKET_ERROR)
{
printf("setsockopt(IP_OPTIONS) failed. %d\n", WSAGetLastError());
}
}

ret = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

if (ret == SOCKET_ERROR)
{
printf("setsockopt(SO_RECVTIMEO) failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}

timeout = 1000;
ret = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));

if (ret == SOCKET_ERROR)
{
printf("setsockopt(SO_SNDTIMEO) failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}

memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
if ((dest.sin_addr.S_un.S_addr = inet_addr(lpDest)) == INADDR_NONE)
{
if ((hp = gethostbyname(lpDest)) == NULL)
{
printf("gethostbyname() failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}
else
{
memcpy(&(dest.sin_addr), hp->h_addr_list, hp->h_length);
dest.sin_family = hp->h_addrtype;
printf("dest.sin_addr = %s\n", inet_ntoa(dest.sin_addr));
}
}

dataSize += sizeof(IcmpHeader);
icmp_data = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET_SIZE);
recv_buf = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET_SIZE);

if (icmp_data == NULL || recv_buf == NULL)
{
printf("HeapAlloc() failed. %d\n", GetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}

FillIcmpHeader(icmp_data, dataSize);

local.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
local.sin_family = AF_INET;

/*
ret = bind(sockRaw, (sockaddr*)&local, sizeof(local));

if (ret == SOCKET_ERROR)
{
printf("setsockopt(SO_SNDTIMEO) failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}
*/

while (1)
{
static int nCount = 0;
int bwrote;

if (nCount ++ == 4)
{
break;
}

((IcmpHeader*)icmp_data)->checksum = 0;
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->seq = seq_no ++;
((IcmpHeader*)icmp_data)->checksum = CheckSum((USHORT*)icmp_data, dataSize);

bwrote = sendto(sockRaw, icmp_data, dataSize, 0, (sockaddr*)&dest, sizeof(sockaddr));

if (bwrote == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf("sendto time out\n");
continue;
}

printf("sendto() failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}

if (bwrote < dataSize)
{
printf("wrote %d bytes\n", bwrote);
}

bread = recvfrom(sockRaw, recv_buf, MAX_PACKET_SIZE, 0, (sockaddr*)&from, &fromlen);

// 总是返回-1,请问为何?
if (bread == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf("recvfrom time out\n");
continue;
}

printf("recvfrom() failed. %d\n", WSAGetLastError());
closesocket(sockRaw);
WSACleanup();
return -1;
}

DecodeIcmpHeader(recv_buf, bread, &from);
Sleep(1000);
}

HeapFree(GetProcessHeap(), 0, recv_buf);
HeapFree(GetProcessHeap(), 0, icmp_data);

closesocket(sockRaw);
WSACleanup();

return 0;
}



...全文
527 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
sillyou 2004-12-30
  • 打赏
  • 举报
回复
To zhangqu_980371: 应该不是timeout设置太小的原因,我IPing的是内网的另一台机器,我将timeout设置成10秒,还是出这个错。
zhangqu_980371 2004-12-30
  • 打赏
  • 举报
回复
timeout设置太小了。才1秒。如果服务器在发送数据前要做一下检查判断,你的客户端都将引起超时。
不过楼主的内存分配方法。呵呵。在普通程序中少见啊。
另外,你也需要调试确认一下服务器端是是否正确发送了数据。
月吻长河 2004-12-30
  • 打赏
  • 举报
回复
:)
scmsir 2004-12-29
  • 打赏
  • 举报
回复
你应该确定服务器端有没有问题。
aoosang 2004-12-29
  • 打赏
  • 举报
回复
那就说明socket上没有东西可以接收啊
HunterForPig 2004-12-27
  • 打赏
  • 举报
回复
你最好用sinffer看看是否确实发送出去了
sillyou 2004-12-23
  • 打赏
  • 举报
回复
WSAGetLastError返回值是 Timeout
ilovevc 2004-12-22
  • 打赏
  • 举报
回复
那就再看WSAGetLastError
anxiangbin 2004-12-22
  • 打赏
  • 举报
回复
晕,傻问题啊?这么代码,没耐心看啊
sillyou 2004-12-22
  • 打赏
  • 举报
回复
UUUUUUUUUUUUUUUP
sillyou 2004-12-21
  • 打赏
  • 举报
回复
请高人相助
sillyou 2004-12-21
  • 打赏
  • 举报
回复
UP

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧