基于VC实现的网络监听功能程序实例

本文所述VC++网络监听器代码,可以实现监听网络连接所使用的协议、源IP地址、目标IP地址等信息的功能,并且能把数据内容绑定到网格控件中显示。具体功能代码部分如下所示:

//线程函数

UINT ThreadFun( LPVOID pParam )

{

CSniffAppDlg* pDlg = static_cast<CSniffAppDlg*>(pParam);

MSG msg;

char buffer[1000],sourceip[32] ,*tempbuf;

char *ptemp;

BYTE* pData = NULL; //实际数据报中的数据

UINT sourceport ;

CString str;

HEADIP* pHeadIP;

HEADICMP* pHeadICMP;

HEADUDP* pHeadUDP;

HEADTCP* pHeadTCP;

in_addr addr;

int ret;

while (TRUE)

{

pData = NULL;

if (PeekMessage(&msg,pDlg->m_hWnd,WM_CLOSE,WM_CLOSE,PM_NOREMOVE ))

{

closesocket(pDlg->m_Sock);

break;

}

memset(buffer,0,1000);

ret = recv(pDlg->m_Sock,buffer,1000,0);

if (ret == SOCKET_ERROR)

{

continue;

}

else //接收到数据

{

tempbuf = buffer;

pHeadIP = (HEADIP*)tempbuf;

//获取数据报总长度

WORD len = ntohs(pHeadIP->totallen);

//获取源IP

pDlg->m_List.InsertItem(pDlg->m_List.GetItemCount(),"");

addr.S_un.S_addr = pHeadIP->sourceIP;

ptemp = inet_ntoa(addr);

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,1,ptemp);

//获取目的IP

addr.S_un.S_addr = pHeadIP->destIP;

ptemp = inet_ntoa(addr);

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,2,ptemp);

//获取协议名称

ptemp = get_protoname(pHeadIP->proto);

strcpy(sourceip,ptemp);

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,0,sourceip);

//获取IP数据报总长度

WORD ipSumLen = ntohs(pHeadIP->totallen);

//IP数据报头总长度

int ipHeadLen = 20;

//获得去除IP层数据的长度

WORD netlen = ipSumLen - ipHeadLen;

//根据不同大协议获得不同协议的数据

switch (pHeadIP->proto)

{

case IPPROTO_ICMP:

{

pHeadICMP = (HEADICMP*)(tempbuf+20);

pData = (BYTE*)(pHeadICMP)+4; //ICMP数据报头共4个字节

//获取数据的长度

netlen -= 4;

break;

}

case IPPROTO_UDP:

{

pHeadUDP = (HEADUDP*)(tempbuf+20);

pData = (BYTE*)pHeadUDP+8; //UDP数据报头共8个字节

sourceport = ntohs(pHeadUDP->SourcePort);

str.Format("%d",sourceport);

//设置源端口

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str);

str.Empty();

netlen -= 8;

break;

}

case IPPROTO_TCP:

{

pHeadTCP = (HEADTCP*)(tempbuf+20);

sourceport = ntohs(pHeadTCP->SourcePort);

pData = (BYTE*)pHeadTCP+20; //TCP数据报头共20个字节

str.Format("%d",sourceport);

//设置源端口

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str);

str.Empty();

netlen-= 20;

break;

}

}

//设置数据大小

str.Format("%d",netlen);

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,4,str);

str.Empty();

//设置数据

if (pData != NULL)

{

str.Format(" %s",pData);

pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,5,str);

}

str.Empty();

}

}

return 0;

}

void CSniffAppDlg::OnBeginlisten()

{

//创建套接字

m_Sock = socket(AF_INET,SOCK_RAW, IPPROTO_IP );

char name[128];

memset(name,0,128);

hostent* phostent;

phostent = gethostbyname(name);

DWORD ip;

ip = inet_addr(inet_ntoa(*(in_addr*)phostent->h_addr_list[0]));

int timeout = 4000; //超时4秒

//设置接收数据的超时时间

setsockopt(m_Sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(timeout));

sockaddr_in skaddr;

skaddr.sin_family = AF_INET;

skaddr.sin_port = htons(700);

skaddr.sin_addr.S_un.S_addr = ip;

//绑定地址

if ( bind(m_Sock,(sockaddr*)&skaddr,sizeof(skaddr))==SOCKET_ERROR)

{

MessageBox("地址绑定错误");

return;

}

DWORD inBuffer=1;

DWORD outBuffer[10];

DWORD reValue = 0;

if (WSAIoctl(m_Sock,SIO_RCVALL,&inBuffer,sizeof(inBuffer),&outBuffer,sizeof(outBuffer),&reValue,NULL,NULL)==SOCKET_ERROR)

{

MessageBox("设置缓冲区错误.");

closesocket(m_Sock);

return;

}

else

m_pThread = AfxBeginThread(ThreadFun,(void*)this);

}

void CSniffAppDlg::OnCancel()

{

if (m_pThread)

{

//m_pThread->ExitInstance();

delete m_pThread;

}

closesocket( m_Sock) ;

CDialog::OnCancel();

}

该实例只是功能部分主要代码,读者可根据自身项目需求进行测试,加以改进与完善之后整合进自身项目中去。

以上是 基于VC实现的网络监听功能程序实例 的全部内容, 来源链接: utcz.com/z/321196.html

回到顶部