原始套接字头结构定义
来源:互联网 发布:分类信息系统源码 编辑:程序博客网 时间:2024/04/29 04:21
头结构定义
/// @file ping.h/// @brief ping需要的数据结构#ifndef __PING_H_2016_0408__#define __PING_H_2016_0408__#pragma pack(push)#pragma pack(1)#define ICMP_ECHOREPLY 0#define ICMP_HOST_NOTEXIST 3 ///< 主机不存在#define ICMP_ECHOREQ 8// IP Header -- RFC 791typedef struct tagIPHDR{ // u_char VIHL; // Version and IHL u_char h_len:4; // length of header u_char version:4; // Version of IP u_char TOS; // Type Of Service short TotLen; // Total Length short ID; // Identification short FlagOff; // Flags and Fragment Offset u_char TTL; // Time To Live u_char Protocol; // Protocol(tcp, udp, etc.) u_short Checksum; // Checksum struct in_addr iaSrc; // Internet Address - Source struct in_addr iaDst; // Internet Address - Destination}IPHDR, *PIPHDR;typedef struct _UDP_HEADER { USHORT nSourPort ; // 源端口号16bit USHORT nDestPort ; // 目的端口号16bit USHORT nLength ; // 数据包长度16bit USHORT nCheckSum ; // 校验和16bit}UDP_HEADER, *PUDP_HEADER;typedef struct _TCP_HEADER { USHORT nSourPort; // 源端口号16bit USHORT nDestPort; // 目的端口号16bit UINT nSequNum; // 序列号32bit UINT nAcknowledgeNum; // 确认号32bit // USHORT nHLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志位16bit USHORT nTcpLen:4; USHORT nTcpUnused:6; USHORT nTcpFlag:6; USHORT nWindowSize; // 窗口大小16bit USHORT nCheckSum; // 检验和16bit USHORT nrgentPointer; // 紧急数据偏移量16bit}TCP_HEADER, *PTCP_HEADER;// ICMP Header - RFC 792typedef struct tagICMPHDR{ u_char Type; // Type u_char Code; // Code u_short Checksum; // Checksum u_short ID; // Identification u_short Seq; // Sequence // char Data; // Data ULONG Data; // Data, for GetTickCount}ICMPHDR, *PICMPHDR;#define REQ_DATASIZE 32 // Echo Request Data size// ICMP Echo Requesttypedef struct tagECHOREQUEST{ ICMPHDR icmpHdr;// DWORD dwTime; char cData[REQ_DATASIZE];}ECHOREQUEST, *PECHOREQUEST;// ICMP Echo Replytypedef struct tagECHOREPLY{ IPHDR ipHdr; ECHOREQUEST echoRequest; char cFiller[256];}ECHOREPLY, *PECHOREPLY;#pragma pack(pop)#endif // #ifndef __PING_H_2016_0408__
应用-ping
// pingUIDlg.h : header file//#if !defined(AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_)#define AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "MyThread.h"#include <list>using namespace std;/////////////////////////////////////////////////////////////////////////////// CPingUIDlg dialogclass CPingUIDlg : public CDialog{// Constructionpublic: CPingUIDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data //{{AFX_DATA(CPingUIDlg) enum { IDD = IDD_PINGUI_DIALOG }; CListBox m_CtrlListBoxMsg; CString m_strIpOrDoMainName; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CPingUIDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CPingUIDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonPing(); afx_msg void OnDestroy(); //}}AFX_MSG afx_msg void OnShowThreadMsg(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP()public: static unsigned __stdcall ThreadProcPing(void* pParam); unsigned ThreadProcPing();private: void DataInit(); void DataUnInit(); void ShowErrMsg(int iErrSn); void ShowSocketErrMsg(); void ShowErrMsg(); void ShowThreadMsg(TCHAR* pMsg); void ClearThreadMsg(); void ShowUiMsg(TCHAR* pcMsg); void Ping(LPCSTR pstrHost); int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr); int WaitForEchoReply(SOCKET s); DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL, DWORD& dwTimeSent); u_short in_cksum(u_short *addr, int len);private: list<CString> m_ListDispMsg; CRITICAL_SECTION g_csDispMsg; CMyThread m_ThreadProcPing;};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_PINGUIDLG_H__C679F26E_6016_4CEE_8821_677F00F4C247__INCLUDED_)
// pingUIDlg.cpp : implementation file//#include "stdafx.h"#include <atlconv.h>#include "pingUI.h"#include "pingUIDlg.h"#include "ping.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif#define WM_SHOW_THREAD_MSG (WM_APP + 1000)/////////////////////////////////////////////////////////////////////////////// CPingUIDlg dialogCPingUIDlg::CPingUIDlg(CWnd* pParent /*=NULL*/) : CDialog(CPingUIDlg::IDD, pParent){ //{{AFX_DATA_INIT(CPingUIDlg) m_strIpOrDoMainName = _T("192.168.2.60"); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CPingUIDlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPingUIDlg) DDX_Control(pDX, IDC_LIST_MSG, m_CtrlListBoxMsg); DDX_Text(pDX, IDC_EDIT_IP_OR_DOMAIN_NAME, m_strIpOrDoMainName); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CPingUIDlg, CDialog) //{{AFX_MSG_MAP(CPingUIDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_PING, OnButtonPing) ON_WM_DESTROY() //}}AFX_MSG_MAP ON_MESSAGE(WM_SHOW_THREAD_MSG, OnShowThreadMsg)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CPingUIDlg message handlersBOOL CPingUIDlg::OnInitDialog(){ CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here DataInit(); return TRUE; // return TRUE unless you set the focus to a control}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CPingUIDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); }}// The system calls this to obtain the cursor to display while the user drags// the minimized window.HCURSOR CPingUIDlg::OnQueryDragIcon(){ return (HCURSOR) m_hIcon;}void CPingUIDlg::OnButtonPing() { UpdateData(TRUE); if (m_strIpOrDoMainName.IsEmpty()) { ShowThreadMsg(_T("请输入IP或域名")); } else { if (m_ThreadProcPing.IsRunning()) { ShowThreadMsg(_T("ping任务还没有结束, 请稍等")); } else { m_ThreadProcPing.SetParam( ThreadProcPing, NULL, NULL, this); m_ThreadProcPing.Start(); } }}unsigned __stdcall CPingUIDlg::ThreadProcPing(void* pParam) { if (NULL == pParam) { return S_FALSE; } return ((CPingUIDlg*)pParam)->ThreadProcPing();}unsigned CPingUIDlg::ThreadProcPing() { ClearThreadMsg(); Ping((LPCTSTR)m_strIpOrDoMainName); ShowThreadMsg(_T("==========任务结束==========")); return S_OK;}void CPingUIDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here m_ThreadProcPing.Stop(); DataUnInit();}void CPingUIDlg::DataInit() { WSADATA m_WSAData; WSAStartup(MAKEWORD(2,2), &m_WSAData); InitializeCriticalSection(&g_csDispMsg);}void CPingUIDlg::DataUnInit() { DeleteCriticalSection(&g_csDispMsg); WSACleanup();}void CPingUIDlg::OnShowThreadMsg(WPARAM wParam, LPARAM lParam) { CString str; EnterCriticalSection(&g_csDispMsg); if (0 == wParam) { while (!m_ListDispMsg.empty()) { str = m_ListDispMsg.front(); m_ListDispMsg.pop_front(); ShowUiMsg((LPTSTR)(LPCTSTR)str); } } else { m_CtrlListBoxMsg.ResetContent(); } LeaveCriticalSection(&g_csDispMsg);}void CPingUIDlg::ShowUiMsg(TCHAR* pcMsg) { int iRc = 0; if (NULL != pcMsg) { iRc = m_CtrlListBoxMsg.AddString(pcMsg); if (LB_ERRSPACE == iRc) { m_CtrlListBoxMsg.ResetContent(); m_CtrlListBoxMsg.AddString(pcMsg); } }}void CPingUIDlg::ShowSocketErrMsg() { int iErrSn = WSAGetLastError(); ShowErrMsg(iErrSn);}void CPingUIDlg::ShowErrMsg() { int iErrSn = GetLastError(); ShowErrMsg(iErrSn);}void CPingUIDlg::ShowErrMsg(int iErrSn) { LPVOID lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, iErrSn, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); if (NULL != lpMsgBuf) { ShowThreadMsg((LPTSTR)lpMsgBuf); } LocalFree(lpMsgBuf);}void CPingUIDlg::ShowThreadMsg(TCHAR* pMsg) { if (NULL != pMsg) { EnterCriticalSection(&g_csDispMsg); m_ListDispMsg.push_back(pMsg); LeaveCriticalSection(&g_csDispMsg); PostMessage(WM_SHOW_THREAD_MSG, 0, 0); }}void CPingUIDlg::ClearThreadMsg() { EnterCriticalSection(&g_csDispMsg); m_ListDispMsg.clear(); LeaveCriticalSection(&g_csDispMsg); PostMessage(WM_SHOW_THREAD_MSG, 1, 0);}void CPingUIDlg::Ping(LPCSTR pstrHost){ CString str; SOCKET rawSocket; LPHOSTENT lpHost; struct sockaddr_in saDest; struct sockaddr_in saSrc; DWORD dwTimeSent = 0; DWORD dwElapsed = 0; DWORD dwTick = 0; u_char cTTL; int nLoop; int nRet; DWORD dwReplyType = ICMP_ECHOREPLY; // Create a Raw socket rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (rawSocket == SOCKET_ERROR) { ShowSocketErrMsg(); return; } // Lookup host lpHost = gethostbyname(pstrHost); if (lpHost == NULL) { str.Format(_T("\nHost not found: %s"), pstrHost); ShowThreadMsg((LPTSTR)(LPCTSTR)str); return; } // Setup destination socket address saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr)); saDest.sin_family = AF_INET; saDest.sin_port = 0; // Tell the user what we're doing str.Format(_T("Pinging %s [%s] with %d bytes of data:\n"), pstrHost, inet_ntoa(saDest.sin_addr), REQ_DATASIZE); ShowThreadMsg((LPTSTR)(LPCTSTR)str); // Ping multiple times for (nLoop = 0; nLoop < 4; nLoop++) { // Send ICMP echo request SendEchoRequest(rawSocket, &saDest); // Use select() to wait for data to be received nRet = WaitForEchoReply(rawSocket); if (nRet == SOCKET_ERROR) { ShowSocketErrMsg(); break; } if (!nRet) { ShowThreadMsg("TimeOut"); continue; } // Receive reply dwReplyType = RecvEchoReply(rawSocket, &saSrc, &cTTL, dwTimeSent); if (ICMP_ECHOREPLY == dwReplyType) { // Calculate elapsed time dwTick = GetTickCount(); dwElapsed = dwTick - dwTimeSent; str.Format(_T("\nReply from: %s: bytes=%d time=%ldms TTL=%d"), inet_ntoa(saSrc.sin_addr), REQ_DATASIZE, dwElapsed, cTTL); } else if (ICMP_HOST_NOTEXIST == dwReplyType) { str = _T("无法访问目标主机"); } else { str.Format(_T("ICMP回答类型为%d, 请联系软件开发者"), dwReplyType); } ShowThreadMsg((LPTSTR)(LPCTSTR)str); } nRet = closesocket(rawSocket); if (nRet == SOCKET_ERROR) ShowSocketErrMsg();}int CPingUIDlg::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr){ static ECHOREQUEST echoReq; static nId = 1; static nSeq = 1; int nRet; // Fill in echo request echoReq.icmpHdr.Type = ICMP_ECHOREQ; echoReq.icmpHdr.Code = 0; echoReq.icmpHdr.Checksum = 0; echoReq.icmpHdr.ID = nId++; echoReq.icmpHdr.Seq = nSeq++; // Fill in some data to send for (nRet = 0; nRet < REQ_DATASIZE; nRet++) echoReq.cData[nRet] = ' '+nRet; // Save tick count when sent echoReq.icmpHdr.Data = GetTickCount(); // Put data in packet and compute checksum echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST)); // Send the echo request nRet = sendto(s, /* socket */ (LPSTR)&echoReq, /* buffer */ sizeof(ECHOREQUEST), 0, /* flags */ (LPSOCKADDR)lpstToAddr, /* destination */ sizeof(SOCKADDR_IN)); /* address length */ if (nRet == SOCKET_ERROR) ShowSocketErrMsg(); return (nRet);}int CPingUIDlg::WaitForEchoReply(SOCKET s){ struct timeval Timeout; fd_set readfds; readfds.fd_count = 1; readfds.fd_array[0] = s; Timeout.tv_sec = 5; Timeout.tv_usec = 0; return(select(1, &readfds, NULL, NULL, &Timeout));}DWORD CPingUIDlg::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL, DWORD& dwTimeSent) { CString str; ECHOREPLY echoReply; int nRet; int nAddrLen = sizeof(struct sockaddr_in); // Receive the echo reply ZeroMemory(&echoReply, sizeof(echoReply)); nRet = recvfrom(s, // socket (LPSTR)&echoReply, // buffer sizeof(ECHOREPLY), // size of buffer 0, // flags (LPSOCKADDR)lpsaFrom, // From address &nAddrLen); // pointer to address len // Check return value if (nRet == SOCKET_ERROR) ShowSocketErrMsg(); // return time sent and IP TTL if (echoReply.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY) { *pTTL = echoReply.ipHdr.TTL; dwTimeSent = echoReply.echoRequest.icmpHdr.Data; } return echoReply.echoRequest.icmpHdr.Type;}//// Mike Muuss' in_cksum() function// and his comments from the original// ping program//// * Author -// * Mike Muuss// * U. S. Army Ballistic Research Laboratory// * December, 1983/* * I N _ C K S U M * * Checksum routine for Internet Protocol family headers (C Version) * */u_short CPingUIDlg::in_cksum(u_short *addr, int len){ register int nleft = len; register u_short *w = addr; register u_short answer; register int sum = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), * we add sequential 16 bit words to it, and at the end, fold * back all the carry bits from the top 16 bits into the lower * 16 bits. */ while( nleft > 1 ) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if( nleft == 1 ) { u_short u = 0; *(u_char *)(&u) = *(u_char *)w ; sum += u; } /* * add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer);}
0 0
- 原始套接字头结构定义
- UNIX环境学习笔记------原始套接字-----IP头部定义
- 原始套接字报文处理时的结构与原理
- 原始套接字类
- 原始套接字
- 原始套接字(服务器端)
- 学习--原始套接字
- 原始套接字
- 原始套接字发包
- 原始套接字 IP_HDRINCL
- Linux--原始套接字
- 原始套接字
- 原始套接字
- 原始套接字
- 原始套接字
- 原始套接字
- 原始套接字SOCK_RAW
- 原始套接字
- 结构-行为-样式-Bootstrap笔记
- 测试一个字符串中各字符出现的次数
- Quartz 2D编程指南(3)路径(Paths)
- Chrome插件会干坏事儿的
- OpenCV一个窗口显示多张图片
- 原始套接字头结构定义
- 计数排序
- Android开发中Handler的经典总结
- interactivePopGestureRecognizer返回时消息传递
- 分辨率 - 物理分辨率 和 视频文件的分辨率
- 基于Qt的图像处理技术和算法
- ionic 自定义图标
- MySQL查询数据
- 文章收藏