关于网友提出的“ 解析发送到本机的数据包的问题在线等待”问题疑问,本网通过在网上对“ 解析发送到本机的数据包的问题在线等待”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 解析发送到本机的数据包的问题在线等待
描述: 读了一段代码,是关于解析发送到本机的数据包,有如下几个问题:
1.端口为什么如此设定?addr_in.sin_port = htons(57274);
2.为什么没有接收到数据?recv函数阻塞了,没有返回.int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);
void main()
{
// 检查 Winsock 版本号,WSAData为WSADATA结构对象
WSADATA wsaData;
SOCKET sock ;
int flag=true;
char LocalName[100];
hostent *pHost;
SOCKADDR_IN addr_in;
char RecvBuf[4096];
#define BUFFER_SIZE 4096
IP ip;
TCP tcp;
WSAStartup(MAKEWORD(2, 2),&wsaData);
// 创建原始套接字
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
// 获取本机名
gethostname((char*)LocalName, sizeof(LocalName)-1);
// 获取本地 IP 地址
pHost = gethostbyname((char*)LocalName);
// 填充SOCKADDR_IN结构
addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; //IP
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
// 把原始套接字sock 绑定到本地网卡地址上
bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in));
// dwValue为输入输出参数,为1时执行,0时取消
DWORD dwValue = 1;
// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
ioctlsocket(sock, SIO_RCVALL, &dwValue);
// 前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:
int i,j;
unsigned char c;
while (true)
{
// 接收原始数据包信息
memset( RecvBuf,0x0,BUFFER_SIZE);
int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);
if (ret > 0)
{
// 对数据包进行分析,并输出分析结果
ip = *(IP*)RecvBuf;
tcp = *(TCP*)(RecvBuf + ip.HdrLen);
//if (ip.DstAddr!=0xffffffffu)
if (ip.DstAddr==0x7200A8C0u) /// 发送到本机的192.168.0.114
// if (ip.SrcAddr ==0x7200A8C0u)
{
TRACE("协议: %s\n",GetProtocolTxt(ip.Protocol));
TRACE("IP源地址: %s\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
TRACE("IP目标地址: %s\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
TRACE("TCP源端口号: %d\n",tcp.SrcPort);
TRACE("TCP目标端口号:%d\n",tcp.DstPort);
TRACE("数据包长度: %d\n",ntohs(ip.TotalLen));
TRACE("长度:%x %x %x %x\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
TRACE("长度:%d %d %d %d\n\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
printf("0000:");
for(i=0;i<>
{
printf("%02x ", (unsigned char )RecvBuf[i]);
if ((i+1)%16==0)
{
putchar(' ');
for(j=0;j<16;j++)
{
c= RecvBuf[i-(15-j)];
if (isprint(c))
putchar(c);
else
putchar('.');
}
printf("\n%04x:",i+1);
}
}
if (((i=ntohs(ip.TotalLen)%16))!=0)
{
for(j=0;j<16-i;j++)
printf(" ");
putchar(' ');
for(j=0;j<>
{
c= RecvBuf[ntohs(ip.TotalLen)-i+j];
if (isprint(c))
putchar(c);
else
putchar('.');
}
}
printf("\n");
}
}
}
getchar();
}
解决方案1: mark
解决方案2: 你要接收到报文就要设置一下了,比如浏览器的端口80,而且上面不但固定了端口,还固定了IP,你的机子的IP是不是上面的IP,不是的话那肯定是收不到的,因为所有到你机子上的包都被它丢掉了
解决方案3: 这个应该只是对固定的端口的数据进行抓包分析吧。
对与封包过滤技术:楼主可以用SPI(应用层封包过滤),NDIS-HOOK,核心层封包过滤。
解决方案4: 1.转化成网络字节顺序!
2.情况就多了
解决方案5: 问题1:端口如何选择,应该用哪个端口?我下载的例子中使用htons(57274),为什么?
问题2:这段代码是解析发送到本机的数据包,为什么向本机发送数据包(我通过浏览网页、用客户端程序连接本机发送数据都尝试过了)时recv函数收不到呢?
to 1:
端口你可以随变乱写,但是必须在1024以上,前1024个端口是系统保留用。
to 2:
情况很多,你先得确定是否连接上了。再看为什么不能收包。
解决方案6: 看了一下msdn中关于socket的recv函数的说明
有一句话是这样说的:
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking
以上介绍了“ 解析发送到本机的数据包的问题在线等待”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3153123.html