有这么一段程序:
int CRecvPackThread::CreateSocket()
{
WSADATA wsd;
SOCKADDR_IN if0;
unsigned int optval = 1;
DWORD dwIoControlCode = SIO_RCVALL,
dwProtocol = IPPROTO_IP,
dwInterface = 0,
dwBytesRet = 0; //初始化函数,MAKEWORD(2,2)宏用于指定版本号,wsd是WSADAEA结构
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
return RET_FALSE;
} // Create a raw socket for receiving IP datagrams
s = WSASocket(AF_INET, SOCK_RAW, dwProtocol, NULL, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET)
{
return RET_FALSE;
} // Get an interface to read IP packets on
if (GetInterface(&if0, dwInterface) != 0)
{
return RET_FALSE;
} // This socket must be bound before calling the ioctl
if0.sin_family = AF_INET;
if0.sin_port = htons(0);
if (bind(s, (SOCKADDR *)&if0, sizeof(if0)) == SOCKET_ERROR)
{
return RET_FALSE;
} // Set the SIO_RCVALLxxx ioctl
if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
{
return RET_FALSE;
} return RET_TRUE;
}int CRecvPackThread::Run()
{
// TODO: Add your specialized code here and/or call the base class
DWORD dwBytesRet = 0,
dwFlags = 0;
int ret = 0;
int ip_head_len=0; ret = CreateSocket();
if(ret != RET_TRUE)
{
return RET_FALSE;
} // Start receiving IP packet until interrupted
wbuf.len = MAX_IP_SIZE;
while (1)
{
wbuf.buf = &RecvBuf[PacketNum * MAX_IP_SIZE];
//use wbuf for receiving packet
ret = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
if (ret == SOCKET_ERROR)
{
continue;
} PacketNum++; if(PacketNum > MOST_PACKET_NUM)
{
break;
}
}
closesocket(s);
WSACleanup(); //开始处理IP包
m_pDealPackThread = new CDealPackThread(); //另一个线程类
m_pDealPackThread->CreateThread(); return CWinThread::Run();
}在倒数第四行处发生了如下错误:Unhandled exception in mailsniffer.exe(MFC42D.DLL):0xC0000005:Access Violation.
调试的时候发现是由WSARecv函数造成的,请问该如何解决?
int CRecvPackThread::CreateSocket()
{
WSADATA wsd;
SOCKADDR_IN if0;
unsigned int optval = 1;
DWORD dwIoControlCode = SIO_RCVALL,
dwProtocol = IPPROTO_IP,
dwInterface = 0,
dwBytesRet = 0; //初始化函数,MAKEWORD(2,2)宏用于指定版本号,wsd是WSADAEA结构
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
return RET_FALSE;
} // Create a raw socket for receiving IP datagrams
s = WSASocket(AF_INET, SOCK_RAW, dwProtocol, NULL, 0, WSA_FLAG_OVERLAPPED);
if (s == INVALID_SOCKET)
{
return RET_FALSE;
} // Get an interface to read IP packets on
if (GetInterface(&if0, dwInterface) != 0)
{
return RET_FALSE;
} // This socket must be bound before calling the ioctl
if0.sin_family = AF_INET;
if0.sin_port = htons(0);
if (bind(s, (SOCKADDR *)&if0, sizeof(if0)) == SOCKET_ERROR)
{
return RET_FALSE;
} // Set the SIO_RCVALLxxx ioctl
if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
{
return RET_FALSE;
} return RET_TRUE;
}int CRecvPackThread::Run()
{
// TODO: Add your specialized code here and/or call the base class
DWORD dwBytesRet = 0,
dwFlags = 0;
int ret = 0;
int ip_head_len=0; ret = CreateSocket();
if(ret != RET_TRUE)
{
return RET_FALSE;
} // Start receiving IP packet until interrupted
wbuf.len = MAX_IP_SIZE;
while (1)
{
wbuf.buf = &RecvBuf[PacketNum * MAX_IP_SIZE];
//use wbuf for receiving packet
ret = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
if (ret == SOCKET_ERROR)
{
continue;
} PacketNum++; if(PacketNum > MOST_PACKET_NUM)
{
break;
}
}
closesocket(s);
WSACleanup(); //开始处理IP包
m_pDealPackThread = new CDealPackThread(); //另一个线程类
m_pDealPackThread->CreateThread(); return CWinThread::Run();
}在倒数第四行处发生了如下错误:Unhandled exception in mailsniffer.exe(MFC42D.DLL):0xC0000005:Access Violation.
调试的时候发现是由WSARecv函数造成的,请问该如何解决?
if(PacketNum > MOST_PACKET_NUM)
{
break;
}
当PacketNum == MOST_PACKET_NUM-1 时,就已经填充IP包内容到缓冲区尾了,因此会在PacketNum == MOST_PACKET_NUM 时,内存非法访问
可能是这个原因,没用程序验证