ScanPortDlg.cpp
资源名称:ScanPort.rar [点击查看]
上传用户:by888888
上传日期:2015-06-24
资源大小:42k
文件大小:13k
源码类别:
Telnet客户端
开发平台:
Visual C++
- // ScanPortDlg.cpp
- //
- //作者 何嘉宁
- #include "stdafx.h"
- #include "ScanPort.h"
- #include "ScanPortDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- //线程返回的错误代码,调试用
- #define ERROR_CREATE_SOCKET -1L
- #define ERROR_MODIFY_FIONBIO -2L
- #define ERROR_SELECT -3L
- #define ERROR_SELECT_TIMEOUT -4L
- //线程发回的消息
- #define SCAN_THREAD WM_USER+100
- //线程发回的消息的wParam参数定义
- #define DOSCAN_FIND_PORT 1 //发现一个开放端口
- #define DOSCAN_END_PORT 2 //完成一个端口扫描
- #define STARTSCAN_COMPLETE 3 //完成所有扫描
- //
- #define MAX_SEPECIEFIED_PORTS 256 //对于扫描指定的端口的最大数
- //全局变量
- HWND g_hWnd = NULL; //处理消息的窗口句柄
- unsigned long g_ulAddr = INADDR_NONE; //扫描的主机地址
- DWORD g_dwTimeOut = 1000; //连接超时时间,以ms计
- bool g_bTerminate = false; //是否用户发出结束扫描的标志
- short g_nMaxThread = 200; //最大允许的扫描线程数,经试验不宜大于200
- short g_nThreadCount = 0; //当前正在扫描的进程数
- /////////////////////////////////////////////////////////////////////////////
- // CAboutDlg dialog used for App About
- struct tag_PORTS
- {
- BOOL bSepecifiedPort;
- union
- {
- struct
- {
- unsigned short iStartPort;
- unsigned short iEndPort;
- };
- struct
- {
- unsigned short nCount;
- unsigned short nArrOfPorts[MAX_SEPECIEFIED_PORTS];
- };
- };
- };
- bool IsIpString(const char* pszHostOrIp)
- {
- if (strlen(pszHostOrIp) > 15)
- {
- return false;
- }
- //创建一个输入字符的副本,防止被修改
- char szHostOrIpCopy[16];
- strcpy(szHostOrIpCopy, pszHostOrIp);
- int nPart = 0;
- char* pszPart = strtok(szHostOrIpCopy, ".");
- while (pszPart != NULL)
- {
- for (unsigned int i=0; i<strlen(pszPart); i++)
- {
- if (pszPart[i]>'9' || pszPart[i]<'0')
- {
- return false;
- }
- }
- if (unsigned int(atoi(pszPart)) > 255)
- {
- return false;
- }
- nPart++;
- pszPart = strtok(NULL, ".");
- }
- return nPart == 4;
- }
- unsigned long GetAddr(const char* pszHostOrIp)
- {
- if (*pszHostOrIp == ' ')
- {
- return inet_addr("127.0.0.1");
- }
- if (IsIpString(pszHostOrIp))
- {
- return inet_addr(pszHostOrIp);
- }
- hostent* pHostent = gethostbyname(pszHostOrIp);
- if (pHostent == NULL)
- {
- return INADDR_NONE;
- }
- return (*(unsigned long*)*pHostent->h_addr_list);
- }
- DWORD WINAPI DoScanPort(LPVOID lpParam)
- {
- DWORD dwRet;
- short nPort = *(short*) lpParam;
- delete lpParam;
- SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
- if(sock == INVALID_SOCKET)
- {
- AfxMessageBox("创建套接字失败!");
- dwRet = ERROR_CREATE_SOCKET;
- }
- else
- {
- unsigned long flag = 1;
- if ((ioctlsocket(sock, FIONBIO, &flag) != 0))
- {
- AfxMessageBox("未能改为非阻塞模式!");
- dwRet = ERROR_MODIFY_FIONBIO;
- }
- else
- {
- sockaddr_in severAddr;
- severAddr.sin_family = AF_INET;
- severAddr.sin_port = htons(nPort);
- severAddr.sin_addr.S_un.S_addr = g_ulAddr;
- connect(sock, (sockaddr*)&severAddr, sizeof(severAddr));
- struct fd_set mask;
- FD_ZERO(&mask);
- FD_SET(sock, &mask);
- struct timeval timeout;
- timeout.tv_sec = g_dwTimeOut / 1000;
- timeout.tv_usec = g_dwTimeOut % 1000;
- switch(select(0, NULL, &mask, NULL, &timeout))
- {
- case -1:
- dwRet = ERROR_SELECT;
- break;
- case 0:
- dwRet = ERROR_SELECT_TIMEOUT;
- break;
- default:
- dwRet = ERROR_SUCCESS;
- };
- }
- closesocket(sock);
- }
- g_nThreadCount --;
- if (dwRet == ERROR_SUCCESS)
- {
- ::SendMessage(g_hWnd, SCAN_THREAD, DOSCAN_FIND_PORT, nPort);
- }
- else
- {
- ::SendMessage(g_hWnd, SCAN_THREAD, DOSCAN_END_PORT, nPort);
- }
- return dwRet;
- }
- DWORD WINAPI StartScan(LPVOID lpParam)
- {
- tag_PORTS* pScanParam = (tag_PORTS*)lpParam;
- DWORD dwThreadId;
- unsigned short i;
- if (pScanParam->bSepecifiedPort)
- {
- for(i=0; i<=pScanParam->nCount; i++)
- {
- if (g_bTerminate)
- {
- break; //用户已发出结束扫描命令
- }
- while(g_nThreadCount >= g_nMaxThread)
- {
- Sleep(10);
- }
- if (CreateThread(NULL, 0, DoScanPort, (LPVOID)new short(pScanParam->nArrOfPorts[i]), 0, &dwThreadId) != NULL)
- {
- g_nThreadCount ++;
- }
- }
- }
- else
- {
- for(i=pScanParam->iStartPort; i<=pScanParam->iEndPort; i++)
- {
- if (g_bTerminate)
- {
- break; //用户已发出结束扫描命令
- }
- while(g_nThreadCount >= g_nMaxThread)
- {
- Sleep(10);
- }
- if (CreateThread(NULL, 0, DoScanPort, (LPVOID)new short(i), 0, &dwThreadId) != NULL)
- {
- g_nThreadCount ++;
- }
- }
- }
- //等待各端口扫描线程结束
- while (g_nThreadCount > 0)
- {
- Sleep(50);
- }
- ::SendMessage(g_hWnd, SCAN_THREAD, STARTSCAN_COMPLETE, 0);
- delete pScanParam;
- return ERROR_SUCCESS;
- }
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CScanPortDlg dialog
- CScanPortDlg::CScanPortDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CScanPortDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CScanPortDlg)
- m_csHostOrIp = _T("");
- m_bIsSpecifiedPort = FALSE;
- m_nMaxThread = 200;
- m_iStartPort = 1;
- m_dwTimeOut = 1000;
- m_iEndPort = 1024;
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- m_hThread = NULL;
- }
- void CScanPortDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CScanPortDlg)
- DDX_Control(pDX, IDC_SPECIFIED_PORTS, m_ctrSpecifiedPorts);
- DDX_Control(pDX, IDC_IS_SPECIFIED_PORT, m_ctrCheck);
- DDX_Control(pDX, IDC_TREE, m_ctrResultTree);
- DDX_Control(pDX, IDC_SCAN, m_ctrBeginScan);
- DDX_Text(pDX, IDC_HOST_OR_IP, m_csHostOrIp);
- DDX_Check(pDX, IDC_IS_SPECIFIED_PORT, m_bIsSpecifiedPort);
- DDX_Text(pDX, IDC_MAX_THREAD, m_nMaxThread);
- DDV_MinMaxUInt(pDX, m_nMaxThread, 50, 200);
- DDX_Text(pDX, IDC_START_PORT, m_iStartPort);
- DDX_Text(pDX, IDC_TIME_OUT, m_dwTimeOut);
- DDV_MinMaxDWord(pDX, m_dwTimeOut, 0, 100000);
- DDX_Text(pDX, IDC_END_PORT, m_iEndPort);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CScanPortDlg, CDialog)
- //{{AFX_MSG_MAP(CScanPortDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_IS_SPECIFIED_PORT, OnIsSpecifiedPort)
- ON_BN_CLICKED(IDC_SCAN, OnScan)
- ON_WM_DESTROY()
- ON_WM_TIMER()
- ON_EN_CHANGE(IDC_SPECIFIED_PORTS, OnChangeSpecifiedPorts)
- //}}AFX_MSG_MAP
- ON_MESSAGE(SCAN_THREAD, OnScanThread)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CScanPortDlg message handlers
- BOOL CScanPortDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // 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
- m_pProgressCtrl = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
- m_pProgressCtrl->SetStep(1);
- ReadDefaultPorts();
- m_csHostOrIp = "localhost";
- UpdateData(false);
- WSADATA wsaData;
- BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
- if(ret != 0)
- {
- MessageBox("初始化网络协议失败!");
- return -1;
- }
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CScanPortDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- // 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 CScanPortDlg::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();
- }
- }
- HCURSOR CScanPortDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
- void CScanPortDlg::OnIsSpecifiedPort()
- {
- BOOL bCheck = m_ctrCheck.GetCheck();
- m_ctrSpecifiedPorts.EnableWindow(bCheck);
- }
- void CScanPortDlg::OnScan()
- {
- if (m_hThread == NULL)
- {
- UpdateData();
- if ((g_ulAddr = GetAddr(m_csHostOrIp)) == INADDR_NONE)
- {
- AfxMessageBox("无法找到主机");
- return;
- }
- m_nHasComplete = 0;
- m_dwPercentSeconds = 0;
- m_pProgressCtrl->SetPos(0);
- m_hParentTree = m_ctrResultTree.InsertItem(m_csHostOrIp+CTime::GetCurrentTime().Format("---扫描时间%H:%M:%S"));
- g_bTerminate = false;
- g_dwTimeOut = m_dwTimeOut;
- g_hWnd = m_hWnd;
- g_nMaxThread = m_nMaxThread;
- g_nThreadCount = 0;
- tag_PORTS* pScanParam = new tag_PORTS;
- pScanParam->bSepecifiedPort = m_bIsSpecifiedPort;
- if (m_bIsSpecifiedPort)
- {
- //指定端口
- short nCount = 0;
- char buff[10];
- for(int i=0; i<m_ctrSpecifiedPorts.GetLineCount(); i++)
- {
- int len = m_ctrSpecifiedPorts.GetLine(i, buff, 9);
- if (len != 0)
- {
- buff[len] = ' ';
- pScanParam->nArrOfPorts[nCount++]= atoi(buff);
- }
- }
- pScanParam->nCount = nCount;
- m_pProgressCtrl->SetRange(0, pScanParam->nCount);
- }
- else
- {
- pScanParam->iStartPort = m_iStartPort;
- pScanParam->iEndPort = m_iEndPort;
- m_pProgressCtrl->SetRange(0, m_iEndPort-m_iStartPort+1);
- }
- DWORD dwThreadId;
- m_hThread = CreateThread(NULL, 0, StartScan, (LPVOID)pScanParam, 0, &dwThreadId);
- m_ctrBeginScan.SetWindowText("结束扫描");
- SetTimer(1, 100, NULL);
- }
- else if (!g_bTerminate)
- {
- g_bTerminate = TRUE;
- m_ctrBeginScan.SetWindowText("正在结束...");
- }
- }
- void CScanPortDlg::OnDestroy()
- {
- TerminateThread(m_hThread, 0);
- m_hThread = NULL;
- KillTimer(1);
- SaveDefaultPorts();
- WSACleanup();
- CDialog::OnDestroy();
- }
- void CScanPortDlg::OnTimer(UINT nIDEvent)
- {
- if (nIDEvent == 1)
- {
- CString s;
- m_dwPercentSeconds++;
- s.Format("用时%3d.%1d秒", m_dwPercentSeconds/10, m_dwPercentSeconds%10);
- GetDlgItem(IDC_TIME)->SetWindowText(s);
- m_pProgressCtrl->SetPos(m_nHasComplete);
- }
- CDialog::OnTimer(nIDEvent);
- }
- void CScanPortDlg::OnScanThread(WPARAM wParam, LPARAM lParam)
- {
- char buff[10];
- switch(wParam)
- {
- case DOSCAN_FIND_PORT:
- sprintf(buff, "%d", short(lParam));
- m_ctrResultTree.InsertItem(buff, m_hParentTree);
- m_ctrResultTree.Expand(m_hParentTree, TVE_EXPAND);
- case DOSCAN_END_PORT:
- m_nHasComplete++;
- break;
- case STARTSCAN_COMPLETE:
- m_hThread = NULL;
- m_ctrBeginScan.SetWindowText("开始扫描");
- KillTimer(1);
- AfxMessageBox("本次扫描结束");
- break;
- default:
- break;
- }
- }
- BOOL CScanPortDlg::PreTranslateMessage(MSG* pMsg)
- {
- //处理回车键
- if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
- {
- return 0;
- }
- return CDialog::PreTranslateMessage(pMsg);
- }
- void CScanPortDlg::ReadDefaultPorts()
- {
- try
- {
- CStdioFile f("DefaultPorts.txt", CFile::modeRead|CFile::typeText);
- CString s, ss;
- while (f.ReadString(ss))
- {
- s += ss;
- s += "rn";
- }
- GetDlgItem(IDC_SPECIFIED_PORTS)->SetWindowText(s);
- f.Close();
- }
- catch(...)
- {
- CString s = "13rn37rn80rn123rn135rn139rn489rn1002";
- GetDlgItem(IDC_SPECIFIED_PORTS)->SetWindowText(s);
- }
- }
- void CScanPortDlg::SaveDefaultPorts()
- {
- CStdioFile f("DefaultPorts.txt", CFile::modeCreate|CFile::modeWrite|CFile::typeText);
- char buff[10];
- for(int i=0; i<m_ctrSpecifiedPorts.GetLineCount(); i++)
- {
- int len = m_ctrSpecifiedPorts.GetLine(i, buff, 9);
- if (len != 0)
- {
- buff[len] = ' ';
- f.WriteString(buff);
- f.WriteString("rn");
- }
- }
- f.Close();
- }
- void CScanPortDlg::OnChangeSpecifiedPorts()
- {
- // TODO: If this is a RICHEDIT control, the control will not
- // send this notification unless you override the CDialog::OnInitDialog()
- // function and call CRichEditCtrl().SetEventMask()
- // with the ENM_CHANGE flag ORed into the mask.
- // TODO: Add your control notification handler code here
- }