【急问】哪位大神教我下,在MFC下如何检查某个IP地址是否是连接状态? [问题点数:30分]

daydayup.wiki 2017-04-27 07:18:04
如题,有没有简单快速的方法,之前没做过这方便的,有好的方法给分啦
...全文
949 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
kakabulusi 2017-06-08
  • 打赏
  • 举报
回复
检查IP地址是否在线,和是否连接到本机是不同的两个概念。 建议撸主先了解清楚了需求再提问。
赵4老师 2017-05-05
  • 打赏
  • 举报
回复
引用 12 楼 qq_32008381 的回复:
楼上的大佬们能讲下ping的缺陷吗,为何还需要开进程设缓冲区呢?担心ping对程序主线程有影响可以开个线程来ping,这样有什么缺陷呢?
参考《Unix编程艺术》
正经的董同学 2017-05-04
  • 打赏
  • 举报
回复
楼上的大佬们能讲下ping的缺陷吗,为何还需要开进程设缓冲区呢?担心ping对程序主线程有影响可以开个线程来ping,这样有什么缺陷呢?
示申○言舌 2017-04-28
  • 打赏
  • 举报
回复
引用 7 楼 sdhexu 的回复:
正解在这里: 方案1、自己写ping函数。这样成功或失败就很容易分析了吧。 方案2、如果你非要用CMD的ping命令,那么,给你的建议是使用管道技术。就是创建一个缓冲区,将子进程ping命令的输出转向到你的缓冲区,然后分析缓冲区内的文本即可。同时还可以隐藏ping窗口。
管道技术请自行百度,下面的供参考。很久以前写的。 启动一个Windows控制台进程,并将其输出转向。 截获目标进程输出的方式: 1、等待目标进程结束后读取缓冲区,并更新。 2、随时读取缓冲区并追加更新到指定输出。(但每次读之前需要清除缓冲区,否则输出重叠)

unsigned long SomeThread( LPVOID pVoid )
{
char Buffer [ 4096 ];
DWORD dwExit = 1;
HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
CString szCurPath  = pDlg->GetFilePath();
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PROCESS_INFORMATION ProcessInfo = { 0 };
TCHAR szCommandLine[ 256 ]; // = _T("c:\\windows\\system32\\cmd.exe /c dir");
_tcscpy_s( szCommandLine, 256, ( szCurPath + _T("VPNRel.EXE")));
ZeroMemory( Buffer, 4096 );

if( ! CreatePipe( &hReadPipe, &hWritePipe, &sa, 0 ))
{
  goto EXIT_THREAD;
}
StartupInfo.cb = sizeof( STARTUPINFO );
GetStartupInfo( &StartupInfo );
StartupInfo.hStdError = hWritePipe;
StartupInfo.hStdOutput = hWritePipe;
StartupInfo.wShowWindow = SW_HIDE;
StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

if( ! CreateProcess( NULL, szCommandLine, NULL, NULL, TRUE, 0, NULL, szCurPath, &StartupInfo, &ProcessInfo ))
{
  goto EXIT_THREAD;
}
//    - 创建目标进程成功,开始等待目标进程结束并监视其输出
// ----------------------------目标进程输出-------------------------------

CloseHandle( hWritePipe );
hWritePipe = NULL;
while( dwExit )
{
  DWORD dwWait = WaitForSingleObject( ProcessInfo.hProcess, 200 );
  DWORD dwReaded;
  ZeroMemory( Buffer, sizeof( Buffer )); // Cleaer Buffer.
  if( ReadFile( hReadPipe, Buffer, 4095, &dwReaded, NULL ) == false )
  {
   if( dwWait == WAIT_TIMEOUT )
    continue;
   else
    break;
  }
  else
  {
#ifdef _UNICODE
   TCHAR szWBuffer[ 4096 ];
   ZeroMemory( szWBuffer, sizeof( TCHAR ) * 4096 );
   MultiByteToWideChar( CP_ACP, 0, Buffer, -1, szWBuffer, 4095 );
   APPEND( szWBuffer );  // ==  m_strSomeEdit += szWBuffer; UpdateData( false );
#else
   APPEND( Buffer ); // ==  m_strSomeEdit += Buffer; UpdateData( false );
#endif
  }
  if( dwWait == WAIT_OBJECT_0 )
   break;
}
//--------------------------目标进程已经结束------------------------------
EXIT_THREAD:
if( ProcessInfo.hProcess != NULL )
  CloseHandle( ProcessInfo.hProcess );
if( hWritePipe != NULL )
  CloseHandle( hWritePipe );
if( hReadPipe != NULL )
  CloseHandle( hReadPipe );
pDlg->m_hThread = NULL;
return 0;
} 
示申○言舌 2017-04-28
  • 打赏
  • 举报
回复
正解在这里: 方案1、自己写ping函数。这样成功或失败就很容易分析了吧。 方案2、如果你非要用CMD的ping命令,那么,给你的建议是使用管道技术。就是创建一个缓冲区,将子进程ping命令的输出转向到你的缓冲区,然后分析缓冲区内的文本即可。同时还可以隐藏ping窗口。
daydayup.wiki 2017-04-28
  • 打赏
  • 举报
回复
管道技术加上createprocess可以解决
daydayup.wiki 2017-04-28
  • 打赏
  • 举报
回复
引用 5 楼 像我这么屌的还有六个的回复:
int i=0; NetworkTest *networktest = (NetworkTest *)pParam; networktest->m_pinglist.ResetContent(); // 创建ICMP回显请求包 // char *ICMPPack; // ICMPPack=new char[networktest->packet]; while (networktest->m_stop)//networktest->m_index { char ICMPPack[1024] = {0} ; PICMP_HEADER pICMPHeader = (PICMP_HEADER)ICMPPack ; pICMPHeader->bType = 8 ; pICMPHeader->bCode = 0 ; pICMPHeader->nId = (USHORT)::GetCurrentProcessId() ; pICMPHeader->nCheckSum = 0 ; pICMPHeader->nTimeStamp = 0 ; memset ( (&ICMPPack[ICMP_HEADER_SIZE]), 'E',ICMP_HEADER_SIZE + networktest->m_packet) ; // 填充数据部分,内容任意 // 初始化WinSock库 WORD wVersionRequested = MAKEWORD( 2, 2 ); WSADATA wsaData; if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) return FALSE ; // 创建原始套接字 SOCKET RawSock = socket ( AF_INET, SOCK_RAW, IPPROTO_ICMP ) ; if ( RawSock == INVALID_SOCKET ) { return FALSE ; } // 设置接收超时为1秒 int nTimeout = networktest->m_time ; int ret = ::setsockopt ( RawSock, SOL_SOCKET,SO_RCVTIMEO, (char*)&nTimeout, sizeof(nTimeout)); char szRecvBuf [ DEF_BUF_SIZE] ; SOCKADDR_IN SourSockAddr ; SOCKADDR_IN DestSockAddr ; DestSockAddr.sin_family = AF_INET; inet_addr(networktest->szDestIp); DestSockAddr.sin_addr.s_addr = inet_addr(networktest->szDestIp) ; DestSockAddr.sin_port = htons ( 0 ) ; char m_str_start[128]; if(networktest->index_stop==true) { networktest->m_pinglist.ResetContent(); wsprintf(m_str_start,"正在ping [%s]",networktest->szDestIp); networktest->m_pinglist.AddString(m_str_start); networktest->index_stop=false; } pICMPHeader->nCheckSum = 0 ; // 初始时校验值为0 pICMPHeader->nSequence = i ; // 序号 pICMPHeader->nTimeStamp = ::GetTickCount() ;// 当前时间 // 计算校验值,校验值要在ICMP数据报创建完才能计算 pICMPHeader->nCheckSum = networktest->GetCheckSum ( (LPBYTE)ICMPPack, ICMP_HEADER_SIZE + networktest->m_packet ) ;// // 发送ICMP数据包 int nRet = ::sendto ( RawSock, ICMPPack, ICMP_HEADER_SIZE + networktest->m_packet,0,(SOCKADDR*)&DestSockAddr, sizeof(DestSockAddr) ) ;// if ( nRet == SOCKET_ERROR ) { networktest->m_pinglist.AddString ( "sendto error!\n" ) ; return FALSE ; } // 接收ICMP响应 int nLen = sizeof(SourSockAddr) ; nRet = ::recvfrom ( RawSock, szRecvBuf, DEF_BUF_SIZE,0,(SOCKADDR*)&SourSockAddr, &nLen ) ; if ( nRet == SOCKET_ERROR ) { if ( ::WSAGetLastError() == WSAETIMEDOUT ) { networktest->m_pinglist.AddString ( "Request Timeout\n" ) ; continue ; } else { networktest->m_pinglist.AddString ( "recvfrom error!\n" ) ; return FALSE ; } } // 计算ICMP数据报的时间差 int nTime = ::GetTickCount() - pICMPHeader->nTimeStamp ; int nRealSize = nRet - IP_HEADER_SIZE - ICMP_HEADER_SIZE ; if ( nRealSize < 0 ) { networktest->m_pinglist.AddString ( "To less recv bytes!\n" ); continue ; } // 检测是否当前所发出的ICMP响应包 PICMP_HEADER pRecvHeader = (PICMP_HEADER)(szRecvBuf+IP_HEADER_SIZE); CString str_all; CString m_TTL; if(networktest->m_check1.GetCheck()) { m_TTL.Format("TTL=%d",nRet); } else m_TTL=""; CString m_replaytime; if(networktest->m_check2.GetCheck()) { m_replaytime.Format("time=%dms ",nTime); } else m_replaytime=""; CString m_packetsize; if(networktest->m_check3.GetCheck()) { m_packetsize.Format("bytes=%d ",nRealSize); } else m_packetsize=""; CString m_ipreplay; if(networktest->m_check4.GetCheck()) { m_ipreplay.Format("replay[%d] from %s :",networktest->m_index,inet_ntoa(SourSockAddr.sin_addr)); } else m_ipreplay=""; str_all=m_ipreplay+m_packetsize+m_replaytime+m_TTL; networktest->m_index++; networktest->m_pinglist.AddString(str_all); networktest->UpdateWindow();//立马刷新显示 Sleep(1000) ;// i++; closesocket(RawSock) ; WSACleanup(); }//循环
这是模拟Ping的底层实现吗
daydayup.wiki 2017-04-28
  • 打赏
  • 举报
回复
引用 8 楼 sdhexu的回复:
[quote=引用 7 楼 sdhexu 的回复:] 正解在这里: 方案1、自己写ping函数。这样成功或失败就很容易分析了吧。 方案2、如果你非要用CMD的ping命令,那么,给你的建议是使用管道技术。就是创建一个缓冲区,将子进程ping命令的输出转向到你的缓冲区,然后分析缓冲区内的文本即可。同时还可以隐藏ping窗口。
管道技术请自行百度,下面的供参考。很久以前写的。 启动一个Windows控制台进程,并将其输出转向。 截获目标进程输出的方式: 1、等待目标进程结束后读取缓冲区,并更新。 2、随时读取缓冲区并追加更新到指定输出。(但每次读之前需要清除缓冲区,否则输出重叠)

unsigned long SomeThread( LPVOID pVoid )
{
char Buffer [ 4096 ];
DWORD dwExit = 1;
HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
CString szCurPath  = pDlg->GetFilePath();
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PROCESS_INFORMATION ProcessInfo = { 0 };
TCHAR szCommandLine[ 256 ]; // = _T("c:\\windows\\system32\\cmd.exe /c dir");
_tcscpy_s( szCommandLine, 256, ( szCurPath + _T("VPNRel.EXE")));
ZeroMemory( Buffer, 4096 );

if( ! CreatePipe( &hReadPipe, &hWritePipe, &sa, 0 ))
{
  goto EXIT_THREAD;
}
StartupInfo.cb = sizeof( STARTUPINFO );
GetStartupInfo( &StartupInfo );
StartupInfo.hStdError = hWritePipe;
StartupInfo.hStdOutput = hWritePipe;
StartupInfo.wShowWindow = SW_HIDE;
StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

if( ! CreateProcess( NULL, szCommandLine, NULL, NULL, TRUE, 0, NULL, szCurPath, &StartupInfo, &ProcessInfo ))
{
  goto EXIT_THREAD;
}
//    - 创建目标进程成功,开始等待目标进程结束并监视其输出
// ----------------------------目标进程输出-------------------------------

CloseHandle( hWritePipe );
hWritePipe = NULL;
while( dwExit )
{
  DWORD dwWait = WaitForSingleObject( ProcessInfo.hProcess, 200 );
  DWORD dwReaded;
  ZeroMemory( Buffer, sizeof( Buffer )); // Cleaer Buffer.
  if( ReadFile( hReadPipe, Buffer, 4095, &dwReaded, NULL ) == false )
  {
   if( dwWait == WAIT_TIMEOUT )
    continue;
   else
    break;
  }
  else
  {
#ifdef _UNICODE
   TCHAR szWBuffer[ 4096 ];
   ZeroMemory( szWBuffer, sizeof( TCHAR ) * 4096 );
   MultiByteToWideChar( CP_ACP, 0, Buffer, -1, szWBuffer, 4095 );
   APPEND( szWBuffer );  // ==  m_strSomeEdit += szWBuffer; UpdateData( false );
#else
   APPEND( Buffer ); // ==  m_strSomeEdit += Buffer; UpdateData( false );
#endif
  }
  if( dwWait == WAIT_OBJECT_0 )
   break;
}
//--------------------------目标进程已经结束------------------------------
EXIT_THREAD:
if( ProcessInfo.hProcess != NULL )
  CloseHandle( ProcessInfo.hProcess );
if( hWritePipe != NULL )
  CloseHandle( hWritePipe );
if( hReadPipe != NULL )
  CloseHandle( hReadPipe );
pDlg->m_hThread = NULL;
return 0;
} 
[/quote] 你的正解,虽然我找到方法了,还是很感谢各位回帖的大神
赵4老师 2017-04-28
  • 打赏
  • 举报
回复
仅供参考:
#include <windows.h>
#include <stdio.h>
#include <string.h>
char YN(int k) {
    FILE *f;
    char fn[40];
    char ln[80];
    char yn;
    int n;

    yn='N';
    sprintf(fn,"d:\\ping%d.txt",k);
    f=fopen(fn,"r");
    if (NULL!=f) {
        n=0;
        while (1) {
            if (NULL==fgets(ln,80,f)) break;//
            if (strstr(ln,"ms ")) {
                yn='Y';
                break;//
            }
            n++;
            if (n>=4) break;//
        }
        fclose(f);
    }
    return yn;
}
void main(int argc,char **argv) {
    char cmdstr[256];
    int i;
    int IP[3];
    char c;

    if (argc<2) {
    USAGE:
        printf("Usage example:\n    %s 192.168.60.\nto test 192.168.60.1-254\n",argv[0]);
        return;
    }
    if (4==sscanf(argv[1],"%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&c)) {
        if (0<=IP[0] && IP[0]<=255
         && 0<=IP[1] && IP[1]<=255
         && 0<=IP[2] && IP[2]<=255
         && '.'==c) {
            for (i=1;i<255;i++) {
                sprintf(cmdstr,"cmd /c ping %s%d -n 1 -w 1000 >d:\\ping%d.txt",argv[1],i,i);
                WinExec(cmdstr,SW_HIDE);
            }
            Sleep(3000);
            for (i=1;i<255;i++) {
                printf("%c %s%d\n",YN(i),argv[1],i);
            }
            Sleep(3000);
            WinExec("cmd /c del /q d:\\ping*.txt",SW_HIDE);
        } else goto USAGE;
    } else goto USAGE;
}
三岁、就很帅 2017-04-28
  • 打赏
  • 举报
回复
int i=0; NetworkTest *networktest = (NetworkTest *)pParam; networktest->m_pinglist.ResetContent(); // 创建ICMP回显请求包 // char *ICMPPack; // ICMPPack=new char[networktest->packet]; while (networktest->m_stop)//networktest->m_index { char ICMPPack[1024] = {0} ; PICMP_HEADER pICMPHeader = (PICMP_HEADER)ICMPPack ; pICMPHeader->bType = 8 ; pICMPHeader->bCode = 0 ; pICMPHeader->nId = (USHORT)::GetCurrentProcessId() ; pICMPHeader->nCheckSum = 0 ; pICMPHeader->nTimeStamp = 0 ; memset ( (&ICMPPack[ICMP_HEADER_SIZE]), 'E',ICMP_HEADER_SIZE + networktest->m_packet) ; // 填充数据部分,内容任意 // 初始化WinSock库 WORD wVersionRequested = MAKEWORD( 2, 2 ); WSADATA wsaData; if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) return FALSE ; // 创建原始套接字 SOCKET RawSock = socket ( AF_INET, SOCK_RAW, IPPROTO_ICMP ) ; if ( RawSock == INVALID_SOCKET ) { return FALSE ; } // 设置接收超时为1秒 int nTimeout = networktest->m_time ; int ret = ::setsockopt ( RawSock, SOL_SOCKET,SO_RCVTIMEO, (char*)&nTimeout, sizeof(nTimeout)); char szRecvBuf [ DEF_BUF_SIZE] ; SOCKADDR_IN SourSockAddr ; SOCKADDR_IN DestSockAddr ; DestSockAddr.sin_family = AF_INET; inet_addr(networktest->szDestIp); DestSockAddr.sin_addr.s_addr = inet_addr(networktest->szDestIp) ; DestSockAddr.sin_port = htons ( 0 ) ; char m_str_start[128]; if(networktest->index_stop==true) { networktest->m_pinglist.ResetContent(); wsprintf(m_str_start,"正在ping [%s]",networktest->szDestIp); networktest->m_pinglist.AddString(m_str_start); networktest->index_stop=false; } pICMPHeader->nCheckSum = 0 ; // 初始时校验值为0 pICMPHeader->nSequence = i ; // 序号 pICMPHeader->nTimeStamp = ::GetTickCount() ;// 当前时间 // 计算校验值,校验值要在ICMP数据报创建完才能计算 pICMPHeader->nCheckSum = networktest->GetCheckSum ( (LPBYTE)ICMPPack, ICMP_HEADER_SIZE + networktest->m_packet ) ;// // 发送ICMP数据包 int nRet = ::sendto ( RawSock, ICMPPack, ICMP_HEADER_SIZE + networktest->m_packet,0,(SOCKADDR*)&DestSockAddr, sizeof(DestSockAddr) ) ;// if ( nRet == SOCKET_ERROR ) { networktest->m_pinglist.AddString ( "sendto error!\n" ) ; return FALSE ; } // 接收ICMP响应 int nLen = sizeof(SourSockAddr) ; nRet = ::recvfrom ( RawSock, szRecvBuf, DEF_BUF_SIZE,0,(SOCKADDR*)&SourSockAddr, &nLen ) ; if ( nRet == SOCKET_ERROR ) { if ( ::WSAGetLastError() == WSAETIMEDOUT ) { networktest->m_pinglist.AddString ( "Request Timeout\n" ) ; continue ; } else { networktest->m_pinglist.AddString ( "recvfrom error!\n" ) ; return FALSE ; } } // 计算ICMP数据报的时间差 int nTime = ::GetTickCount() - pICMPHeader->nTimeStamp ; int nRealSize = nRet - IP_HEADER_SIZE - ICMP_HEADER_SIZE ; if ( nRealSize < 0 ) { networktest->m_pinglist.AddString ( "To less recv bytes!\n" ); continue ; } // 检测是否当前所发出的ICMP响应包 PICMP_HEADER pRecvHeader = (PICMP_HEADER)(szRecvBuf+IP_HEADER_SIZE); CString str_all; CString m_TTL; if(networktest->m_check1.GetCheck()) { m_TTL.Format("TTL=%d",nRet); } else m_TTL=""; CString m_replaytime; if(networktest->m_check2.GetCheck()) { m_replaytime.Format("time=%dms ",nTime); } else m_replaytime=""; CString m_packetsize; if(networktest->m_check3.GetCheck()) { m_packetsize.Format("bytes=%d ",nRealSize); } else m_packetsize=""; CString m_ipreplay; if(networktest->m_check4.GetCheck()) { m_ipreplay.Format("replay[%d] from %s :",networktest->m_index,inet_ntoa(SourSockAddr.sin_addr)); } else m_ipreplay=""; str_all=m_ipreplay+m_packetsize+m_replaytime+m_TTL; networktest->m_index++; networktest->m_pinglist.AddString(str_all); networktest->UpdateWindow();//立马刷新显示 Sleep(1000) ;// i++; closesocket(RawSock) ; WSACleanup(); }//循环
三岁、就很帅 2017-04-28
  • 打赏
  • 举报
回复
就是实现CMD命令模式下 发送ping 命令 接收回复的码
daydayup.wiki 2017-04-27
  • 打赏
  • 举报
回复
引用 2 楼 Eleven的回复:
netstat -n 这样的?
不是,比如我要ping 192.168.1.1,怎么才能知道是ping通了还是没有ping通,要在mfc里实现
Eleven 2017-04-27
  • 打赏
  • 举报
回复
netstat -n 这样的?
daydayup.wiki 2017-04-27
  • 打赏
  • 举报
回复
我是MFC新手,看网上说可以用SHELLEXEC调用Ping来做这个,不知道具体怎么实现

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧