衡水网站建设优化排名,郑州网站建设技术,莆田系医院的网站用什么做的,宁波住房与城乡建设部网站UDP端口可达性检测(端口扫描)工具开发
1、应用场景分析
主机X与主机Y部署在AB双网环境下#xff0c;两个主机间通过UDP协议进行数据交互。应用程序发送数据时#xff0c;优先使用A网发送数据#xff0c;如果A网异常则通过B网发送数据。两个主机应用间没有设置心跳帧 …UDP端口可达性检测(端口扫描)工具开发
1、应用场景分析
主机X与主机Y部署在AB双网环境下两个主机间通过UDP协议进行数据交互。应用程序发送数据时优先使用A网发送数据如果A网异常则通过B网发送数据。两个主机应用间没有设置心跳帧 所以无法检测到对方UDP端口是否可达。 场景诉求
主机间发送UDP数据前应能检测对方端口是否可达。如果不可达则进行A/B网切换。达到动态检测对方网络服务端口状态实时切换网络链路效果。
①、 主机不可达
场景分析
主机关机。防火墙开启策略。网卡故障、网线连接异常。网络配置错误。
场景应对策略
通过PING echo 判断主机是否可达。
②、 端口不可达
主机可达端口不可达。
场景分析
服务未启动端口未监听。防火墙开启策略。
场景应对策略
结合ICMP和内核网络协议栈判断UDP端口是否可达。
2、UDP端口扫描程序开发
①、Windows程序
【1】、 理论知识
略。
【2】、 C源码
界面控件设计。 对话框初始化部分代码。
BOOL CUdpDetectDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX 0xFFF0) IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX 0xF000);CMenu* pSysMenu GetSystemMenu(FALSE);if (pSysMenu ! NULL){BOOL bNameValid;CString strAboutMenu;bNameValid strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu-AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。 当应用程序主窗口不是对话框时框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标// 初始化Windows套接字WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), wsaData) ! 0){CString strMsg;strMsg.Format(WSAStartup失败!);return 0;}// CListCtrlDWORD dwStyle m_ListCtrl.GetExtendedStyle();m_ListCtrl.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT );m_ListCtrl.InsertColumn(0, _T(主机端口), LVCFMT_LEFT, 130);m_ListCtrl.InsertColumn(1, _T(扫描结果), LVCFMT_LEFT, 100);m_ListCtrl.InsertColumn(2, _T(ICMP反馈), LVCFMT_LEFT, 350);// 默认参数;m_EditScanHostIP.SetWindowText(192.168.58.1);m_EditScanPortStartNo.SetWindowText(50000);m_EditScanEndPortNo.SetWindowText(50005);return TRUE; // 除非将焦点设置到控件否则返回 TRUE
}端口扫描部分代码。
//扫描端口;
void CUdpDetectDlg::ScanPort()
{CString strScanHost;m_EditScanHostIP.GetWindowText(strScanHost);CString strScanStartPort;m_EditScanPortStartNo.GetWindowText(strScanStartPort);CString strScanEndPort;m_EditScanEndPortNo.GetWindowText(strScanEndPort);int iStartPort _ttoi(strScanStartPort);int iEndPort _ttoi(strScanEndPort);if (iEndPort iStartPort) return;m_ListCtrl.DeleteAllItems();for (int ii iStartPort; ii iEndPort;ii){BOOL isPortOpenF FALSE;char szErrText[256] { 0 };sock socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (sock 0) return;//设置收发缓冲区大小;int iTemp 1024 * 2;setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)iTemp, sizeof(iTemp));setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)iTemp, sizeof(iTemp));//设置接收超时;int iRecvTimeout 1000;setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)iRecvTimeout, sizeof(iRecvTimeout));struct sockaddr_in txaddr;txaddr.sin_family AF_INET;txaddr.sin_addr.s_addr inet_addr(strScanHost.GetBuffer(0));txaddr.sin_port htons(ii);int addrlen sizeof(txaddr);char txbuff[] ;int txlen sendto(sock, txbuff, sizeof(txbuff), 0, (sockaddr*)txaddr, addrlen);char rxbuff[24] { 0 };int rxlen recvfrom(sock, rxbuff, 24, 0, (sockaddr*)txaddr, addrlen);if (rxlen 0){if (WSAGetLastError() WSAECONNRESET){FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL, WSAECONNRESET, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szErrText, 256, NULL);isPortOpenF FALSE;}elseisPortOpenF TRUE;}CString strHostDesc;strHostDesc.Format(%s:%d, strScanHost, ii);CString strPortState;if (isPortOpenF)strPortState.Format(端口可达);elsestrPortState.Format(端口不可达);int iIndex m_ListCtrl.GetItemCount();m_ListCtrl.InsertItem(iIndex, strHostDesc);m_ListCtrl.SetItemText(iIndex, 1, strPortState);m_ListCtrl.SetItemText(iIndex, 2, CString(szErrText));closesocket(sock);}
}【3】、 编译程序 【4】、 运行程序
先将目标主机的50001端口开启监听。然后用测试程序检测。 开始扫描端口。 ②、 Linux程序
【1】、 理论知识
略。
【2】、 C源码
UdpScan.cxx
#include stdio.h
#include stdlib.h
#include unistd.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include errno.h
#include string
#includealgorithmint main()
{printf(*********************************************************************\n);printf(* *\n);printf(* Linux 端口扫描工具 V0.1 *\n);printf(* *\n);printf(*********************************************************************\n);printf(请输入扫描主机IP地址: );char input[256] {0};char* ptr fgets(input,256,stdin);if(ptr nullptr) { printf(输入参数异常结束程序!\n); }std::string strHost std::string(ptr);printf(请输入扫描UDP端口范围(比如2000-2500): );ptr fgets(input,256,stdin);if(ptr nullptr) { printf(输入参数异常结束程序!\n); }std::string strPort std::string(ptr);int iStartPort 0, iEndPort 0;int pos strPort.find(-);if(pos ! std::string::npos){std::string strStartPort strPort.substr(0,pos);std::string strEndPort strPort.substr(pos1);iStartPort std::stoi(strStartPort);iEndPort std::stoi(strEndPort);}if(iEndPort iStartPort) return 1;for(int ii iStartPort; ii iEndPort; ii){ int sock socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//将ICMP端口不可达信息报到应用层协议int flag 1; setsockopt(sock, IPPROTO_IP, IP_RECVERR , flag,sizeof(int)); //设置接收超时struct timeval timeout {0,300};setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)timeout, sizeof(struct timeval));struct sockaddr_in addr;addr.sin_family AF_INET;addr.sin_addr.s_addr inet_addr(strHost.c_str());addr.sin_port htons(ii);char txbuff[] ; int ret sendto(sock,txbuff,sizeof(txbuff),0,(struct sockaddr*)addr,sizeof(addr)); char rxbuff[24] { 0 };int addrlen sizeof(addr);int rxlen recvfrom(sock, rxbuff, sizeof(rxbuff), 0, (struct sockaddr *)addr, addrlen);if (rxlen -1){//剔除回车符strHost.erase(std::remove(strHost.begin(), strHost.end(), \n), strHost.end());if (errno ECONNREFUSED){printf(主机【%s:%d】端口不可达\n,strHost.c_str(),ii);}elseprintf(主机【%s:%d】端口可达\n,strHost.c_str(),ii);} close(sock);}printf(端口扫描结束!\n);return 0;
}
代码截图 【3】、 编译程序
g -o udpscan UdpScan.cxx -fpermissive -stdc11 -w -W【4】、 运行程序
先将目标主机的50001端口开启监听。然后用测试程序检测。 开始扫描端口。