帮忙看下socket的一段代码

nizainade 2007-09-24 11:57:32
代码如下:
int iSendLen=sizeof(IcmpHeader)+PACKET_SIZE;
char * pSendBuf=new char[iSendLen];
struct sockaddr_in socDest;
strIP="192.168.10.122";

socket sockRaw;
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,1),&wsaData) != 0)
{
fprintf(stderr,"WSAStartup failed: %d\n",GetLastError());
exit(1);
}

sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
if(INVALID_SOCKET==sockRaw)
{
printf("invalid socket!\n");
exit(1);
}

FillIcmpPackets((IcmpHeader*)pSendBuf,iSendLen);

socDest.sin_addr.s_addr=inet_addr(strIP);
socDest.sin_family=AF_INET;

int iSendNum;
if(SOCKET_ERROR==(iSendNum = sendto(sockRaw,pSendBuf,iSendLen,0, \
(sockaddr *)&socDest,sizeof(socDest))))
{
printf("sendto failed!\n");
closesocket(sockRaw);
exit(1);
}
printf("have sent to %s %d packets!\n",(char *)strIP,iSendNum);

fd_set fds;
FD_ZERO(&fds);
FD_SET(sockRaw,&fds);
timeval iTimeval={1,0};
int iResult=select(NULL,&fds,0,0,&iTimeval);

上面这段代码就是用sendto发送一个包,然后用select判断socket是否是可读的,进一步再接收。上面192.168.10.122肯定是可以ping通的但是select老是返回0,这是什么原因?
...全文
240 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
nizainade 2007-09-25
  • 打赏
  • 举报
回复
但是校验和的计算不太明白,请指教一下:
USHORT CSend::GenerateIPChecksum(USHORT* pBuffer, int nSize)
{
unsigned long cksum = 0;

while (nSize > 1)
{
cksum += *pBuffer++;
nSize -= sizeof(USHORT);
}

if (nSize)
cksum += *(UCHAR*)pBuffer;
//上面应该是得到cksum每两个字节的累加和
cksum = (cksum >> 16) + (cksum & 0xffff);//
cksum += (cksum >>16); // 这两句代码是什么意思?
return (USHORT)(~cksum);
}
nizainade 2007-09-25
  • 打赏
  • 举报
回复
找到原因了,原来是校验和没有赋值清楚,真是郁闷了几天,看来想当然的拷贝代码是要受惩罚的,呵呵!
CodeGhost 2007-09-25
  • 打赏
  • 举报
回复
sorry,应该是这样的:
以太网头:6字节目的网卡mac地址,6字节源网卡mac地址,协议类型2字节(0x0800,IP)
IP头:版本+头长(1字节,45),1字节不清楚(00),2字节包长度(003c),2字节标识(9b92),分段标识+分段偏移量2字节(0000),1字节TTL(40),1字节协议(01,icmp),2字节头检验和(5248),4字节源IP,4字节目的IP
icmp: 1字节icmp类型(08,echo request), 1字节icmp代码(00),2字节icmp校验和(365c),2字节标识(0200),2字节序列号(1500),32字节icmp数据
整个icmp报文78字节,实际报文长度74字节
CodeGhost 2007-09-25
  • 打赏
  • 举报
回复
ip头长20字节
ping包内容:
以太网头:6字节目的网卡mac地址,6字节源网卡mac地址,协议类型1字节(0x0800,IP)
IP头:版本+头长(1字节,45那个字节),1字节不清楚,2字节包长度(3c),2字节标识,1字节分段标识,2字节分段偏移量,1字节TTL,1字节协议(icmp),2字节头检验和,4字节源IP,4字节目的IP
icmp: 1字节icmp类型(8,echo request), 1字节icmp代码,2字节icmp校验和,2字节标识,2字节序列号,32字节icmp数据
整个icmp报文78字节,实际报文长度74字节
ouyh12345 2007-09-25
  • 打赏
  • 举报
回复
协议我记不清了,得查资料。
具体得看icmp协议
nizainade 2007-09-25
  • 打赏
  • 举报
回复
我用的抓包工具是 ethereal,也不太会用,下面是程序发送的包,
0000 00 14 f6 42 a1 75 00 19 21 be 0c e9 08 00 45 00 ...B.u.. !.....E.
0010 00 40 9b c6 00 00 40 01 52 10 c0 a8 0a 7a c0 a8 .@....@. R....z..
0020 01 1c 08 00 01 00 00 00 01 00 00 00 00 00 77 77 ........ ......ww
0030 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwww wwwwwwww
0040 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwww wwwwww

这是ping包的内容:
0000 00 14 f6 42 a1 75 00 19 21 be 0c e9 08 00 45 00 ...B.u.. !.....E.
0010 00 3c 9b 92 00 00 40 01 52 48 c0 a8 0a 7a c0 a8 .<....@. RH...z..
0020 01 1c 08 00 36 5c 02 00 15 00 61 62 63 64 65 66 ....6\.. ..abcdef
0030 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 ghijklmn opqrstuv
0040 77 61 62 63 64 65 66 67 68 69 wabcdefg hi

两者区别就是ip头部和icmp头部,请问ip头部有多少字节,前面的头部怎么区分啊

ouyh12345 2007-09-25
  • 打赏
  • 举报
回复
那就是楼主的包的问题。
用抓包工具仔细分析
nizainade 2007-09-25
  • 打赏
  • 举报
回复
就是没有抓到返回的包,所以才有问题

我手动ping程序中的主机,测试工具能够抓到发送的包和返回的包,而我的程序就只能抓到发送的包,看来是包没有返回
ouyh12345 2007-09-25
  • 打赏
  • 举报
回复
如果没有返回的包,则select肯定返回0。
ping一下,抓ping的包,分析一下格式,看楼主发的包与ping包有什么区别
ouyh12345 2007-09-25
  • 打赏
  • 举报
回复
我用抓包工具测试发现程序能够发送出去包,而且测试工具标志的是 icmp(ping)request

有没有抓到返回的包?
nizainade 2007-09-25
  • 打赏
  • 举报
回复
请各位帮忙看看是什么问题,已经困扰我几天了,我用抓包工具测试发现程序能够发送出去包,而且测试工具标志的是 icmp(ping)request,和windows的ping一样,但是就是没有返回的包,这可能是什么原因呢
nizainade 2007-09-25
  • 打赏
  • 举报
回复
差不多搞清楚了,校验和的计算,多谢ouyh12345(五岭散人)每次都热心回答问题,感谢!
nizainade 2007-09-24
  • 打赏
  • 举报
回复
楼上的,我也知道是这样,关键是为什么会接收不到而超时呢,上面是刚刚发送出去的包,应该会立即返回的
WizardK 2007-09-24
  • 打赏
  • 举报
回复
返回0表示超时,没有数据可接收

18,356

社区成员

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

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