获取本机收到的UDP数据包的目标地址
来源:互联网 发布:支持微信提现赚钱软件 编辑:程序博客网 时间:2024/05/16 14:34
本机收到UDP数据时,通过recvfrom函数可以直接获取发送者的地址:
int recvfrom( __in SOCKET s, __out char* buf, __in int len, __in int flags, __out struct sockaddr* from, __in_out int* fromlen);
但recvfrom没有提供获取包的目标地址的方法,不久前遇到一个需要获取收到包的目标地址的情况,并找到了解决办法。WinSock提供了WSARecvMsg函数来解决类似问题:
int WSARecvMsg( __in SOCKET s, __in_out LPWSAMSG lpMsg, __out LPDWORD lpdwNumberOfBytesRecvd, __in LPWSAOVERLAPPED lpOverlapped, __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
示例代码如下:
#include <WinSock2.h>#include <MSWSock.h>#include <WS2tcpip.h>#include <Windows.h>#include <stdio.h>#pragma comment(lib, "Ws2_32.lib")int main(){ WSADATA wd; WSAStartup(MAKEWORD(2, 2), &wd); SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(3333); if (SOCKET_ERROR == bind(sock, (sockaddr *)&sin, sizeof(sin))) { closesocket(sock); return 0; } int optval = 1; if (SOCKET_ERROR == setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char*)&optval, sizeof(int))) { closesocket(sock); return 0; } GUID guidWSARecvMsg = WSAID_WSARECVMSG; LPFN_WSARECVMSG lpfnWSARecvMsg = NULL; DWORD dwOutSize = 0; WSAIoctl( sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidWSARecvMsg, sizeof(guidWSARecvMsg), &lpfnWSARecvMsg, sizeof(lpfnWSARecvMsg), &dwOutSize, NULL, NULL ); if (lpfnWSARecvMsg == NULL) { closesocket(sock); return 0; } while (TRUE) { char szControlBuffer[1024] = ""; char szDataBuffer[1024] = ""; sockaddr_in sin_local; WSABUF wsaBufData; WSAMSG wsaMsg; DWORD dwBytesRecved = 0; wsaBufData.buf = szDataBuffer; wsaBufData.len = sizeof(szDataBuffer); wsaMsg.name = (sockaddr *)&sin_local; wsaMsg.namelen = sizeof(sin_local); wsaMsg.lpBuffers = &wsaBufData; wsaMsg.dwBufferCount = 1; wsaMsg.Control.buf = szControlBuffer; wsaMsg.Control.len = sizeof(szControlBuffer); wsaMsg.dwFlags = 0; if (0 == lpfnWSARecvMsg(sock, &wsaMsg, &dwBytesRecved, NULL, NULL)) { WSACMSGHDR *pCMsgHdr = WSA_CMSG_FIRSTHDR(&wsaMsg); if (pCMsgHdr != NULL) { if (pCMsgHdr->cmsg_type == IP_PKTINFO) { IN_PKTINFO *pPktInfo = (IN_PKTINFO *)WSA_CMSG_DATA(pCMsgHdr); if (pPktInfo != NULL) { printf( "%d.%d.%d.%d:%d->%d.%d.%d.%d:%d %s\n", sin_local.sin_addr.S_un.S_un_b.s_b1, sin_local.sin_addr.S_un.S_un_b.s_b2, sin_local.sin_addr.S_un.S_un_b.s_b3, sin_local.sin_addr.S_un.S_un_b.s_b4, ntohs(sin_local.sin_port), pPktInfo->ipi_addr.S_un.S_un_b.s_b1, pPktInfo->ipi_addr.S_un.S_un_b.s_b2, pPktInfo->ipi_addr.S_un.S_un_b.s_b3, pPktInfo->ipi_addr.S_un.S_un_b.s_b4, 3333, szDataBuffer ); } } } } else { break; } } closesocket(sock); return 0;}
运行效果如下,可以审计到各个本机地址,甚至环回地址也能精确捕获:
WSARecvMsg从Windows2000后都可用,与此对应的WSASendMsg函数却是从vista平台才可以提供的。linux平台中有个recvmsg函数应该可以达到类似的目的。本文中的程序在vs2008中编译通过。
- 获取本机收到的UDP数据包的目标地址
- 获取本机收到的UDP数据包的目标地址
- 获取本机的地址
- 局域网UDP异步传输,只收到命令号,数据包的内容是空的
- 获取本机IP地址的脚本
- java获取本机的ip地址
- 获取本机的IP地址代码
- 获取本机的IP地址
- 获取本机的IP地址代码
- 获取本机mac地址的方法
- C#获取本机的MAC地址
- [VB]获取本机的IP地址
- C#获取本机的MAC地址
- 获取本机的IP地址
- 获取本机网卡的MAC地址?
- 获取本机的真实IP地址
- 获取本机IP地址的方法:
- c++获取本机的MAC地址
- VPN: centos vps + pptp
- C复杂声明解析
- Struts2动态下拉列表实现【action+struts2标签】
- 应聘时漂亮的回答,一生受益的语言
- present 一个页面后 使用pushviewcontroller的问题
- 获取本机收到的UDP数据包的目标地址
- 马化腾:微信拿到只是“站票” 我还会有紧迫感
- 国内知名IT产品及其开发语言v0.0.1
- 关于createUrl和CHtml::link参数设置的区别
- 绘制 .9 图片
- 糖果传递问题和仓库运输问题
- 关于SDK回调Qt函数的问题
- IOCP模型与EPOLL模型的比较
- IOS开发(56)之并发简介