對網路編程比較迷茫,請教。。。
設計程式,其功能是發送ICMP資料包,以獲取局域網中的活動主機,并將結果顯示vs2010 MFC圖形界面上,要能直接運行的。。。
uj5u.com熱心網友回復:
網路使用ICMP發現局域網內活動主機uj5u.com熱心網友回復:
http://wenku.baidu.com/link?url=ImEIZVy3K8W31FWMo95ePzCZdKz5TJ6UcMH3b-5lfft8LDaaqHZPQViNrCChgqjfIyH5bnd7vVaaHmRtRxS-BcnkHlv5wPjanegGRKLYegWuj5u.com熱心網友回復:
我需要把IP地址運行結果輸出在一個圖形界面上,就是用把運行結果放在mfc圖形界面上。。。這個報告上面是沒有圖形界面的。。
uj5u.com熱心網友回復:
http://wangbaiyuan.cn/c-activity-host-scans.html你自己把控制臺的修改成GUI的即可,應該還是很簡單的~
uj5u.com熱心網友回復:
參見msdn例程 SendARP()ms-help://MS.MSDNQTR.v90.chs/iphlp/iphlp/sendarp.htm
//The following code demonstrates how to obtain the hardware or media access control (MAC) address associated with a specified IPv4 address.
/* sendarp.c
*
* Link with wsock2.lib and iphlpapi.lib
*/
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
void usage(char *pname)
{
printf("Usage: %s [options] ip-address\n", pname);
printf("\t -h \t\thelp\n");
printf("\t -l length \tMAC physical address length to set\n");
printf("\t -s src-ip \tsource IP address\n");
exit(1);
}
int __cdecl main(int argc, char **argv)
{
DWORD dwRetVal;
IPAddr DestIp = 0;
IPAddr SrcIp = 0; /* default for src ip */
ULONG MacAddr[2]; /* for 6-byte hardware addresses */
ULONG PhysAddrLen = 6; /* default to length of six bytes */
char *DestIpString = NULL;
char *SrcIpString = NULL;
BYTE *bPhysAddr;
int i;
if (argc > 1) {
for (i = 1; i < argc; i++) {
if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
switch (tolower(argv[i][1])) {
case 'l':
PhysAddrLen = (ULONG) atol(argv[++i]);
break;
case 's':
SrcIpString = argv[++i];
SrcIp = inet_addr(SrcIpString);
break;
case 'h':
default:
usage(argv[0]);
break;
} /* end switch */
} else
DestIpString = argv[i];
} /* end for */
} else
usage(argv[0]);
if (DestIpString == NULL || DestIpString[0] == '\0')
usage(argv[0]);
DestIp = inet_addr(DestIpString);
memset(&MacAddr, 0xff, sizeof (MacAddr));
printf("Sending ARP request for IP address: %s\n", DestIpString);
dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen);
if (dwRetVal == NO_ERROR) {
bPhysAddr = (BYTE *) & MacAddr;
if (PhysAddrLen) {
for (i = 0; i < (int) PhysAddrLen; i++) {
if (i == (PhysAddrLen - 1))
printf("%.2X\n", (int) bPhysAddr[i]);
else
printf("%.2X-", (int) bPhysAddr[i]);
}
} else
printf
("Warning: SendArp completed successfully, but returned length=0\n");
} else {
printf("Error: SendArp failed with error: %d", dwRetVal);
switch (dwRetVal) {
case ERROR_GEN_FAILURE:
printf(" (ERROR_GEN_FAILURE)\n");
break;
case ERROR_INVALID_PARAMETER:
printf(" (ERROR_INVALID_PARAMETER)\n");
break;
case ERROR_INVALID_USER_BUFFER:
printf(" (ERROR_INVALID_USER_BUFFER)\n");
break;
case ERROR_BAD_NET_NAME:
printf(" (ERROR_GEN_FAILURE)\n");
break;
case ERROR_BUFFER_OVERFLOW:
printf(" (ERROR_BUFFER_OVERFLOW)\n");
break;
case ERROR_NOT_FOUND:
printf(" (ERROR_NOT_FOUND)\n");
break;
default:
printf("\n");
break;
}
}
return 0;
}
如果采用單執行緒方式,會很慢,從1-255順序發送的話。
可以為了節省時間來改成多執行緒方式,分成1-64;65-127;128-191;192-255四段區間,用4個執行緒同時掃描
------------------------
typedef struct ipmac
{
char szIp[16];
char szMac[6];
}IPMAC;
IPMAC host[255];
int k=0;
CRITICAL_SECTION cs;
/*執行緒函式,用來查詢IP對應的MAC地址*/
DWORD WINAPI ArpThread(LPVOID lParam)
{
char * szIp=(char *)lParam;
ULONG pMac[2];
ULONG pulen=6;
int ret;
TRACE(szIp);
if ((ret=SendARP(inet_addr(szIp),0,pMac,&pulen))==0)
{
EnterCriticalSection(&cs); //多執行緒同步,呵呵:0
strcpy(host[k].szIp,szIp);
PBYTE pbyte=(PBYTE)pMac;
for (int i=0;i<5;i++)
{
host[k].szMac[i]=pbyte[i];
TRACE("%02X-",pbyte[i]);
}
TRACE("%02X",pbyte[5]);
host[k].szMac[5]=pbyte[5];
k++;
LeaveCriticalSection(&cs);
}
else
{
TRACE("SendARP Error %d",ret);
}
return 0;
}
/*列舉局域網內所有主機,并將IP/MAC對插入ListBox中顯示*/
void CTestArpDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HANDLE hthread[254];
CString IpSuffix="192.168.10.";
CString strIp[254];
InitializeCriticalSection(&cs);
for (int i=0;i<254;i++)
{
strIp[i].Format("%d",i+1);
strIp[i]=IpSuffix+strIp[i];
hthread[i]=CreateThread(NULL,0,ArpThread,strIp[i].GetBuffer(0),0,NULL);
}
/*呵呵,因為一次只能等待 64個內核物件,所以只有分幾次了*/
/*當然也可以用回圈了*/
WaitForMultipleObjects(64,hthread,TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[64],TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[128],TRUE,INFINITE);
WaitForMultipleObjects(62,&hthread[192],TRUE,INFINITE);
DeleteCriticalSection(&cs);
CString temp;
for (i=0;i {
PBYTE pmac=(PBYTE)host[i].szMac;
temp.Format("%s(%02x-%02x-%02x-%02x-%02x-%02x)",host[i].szIp,pmac[0],pmac[1],pmac[2],pmac[3],pmac[4],pmac[5]);
m_list.AddString(temp);
}
}
uj5u.com熱心網友回復:
萌新樓主剛學網路這一塊,需要將ip結果輸出到圖形界面,對于GUI實在無感
uj5u.com熱心網友回復:
僅供參考:#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;
}
uj5u.com熱心網友回復:
用ICMP探測主機還是比較慢的,如果攤上一個A類或者B類的子網,你的程式可能需要很長時間才能夠回傳。推薦使用ARP協議去探測主機,只需要偽造一個你是網關的ARP發送出去,然后局域網內的所有主機都會給你發送資料,你就可以獲得所有主機的IP和MAC了。這個程序很快,幾秒鐘就可以了
uj5u.com熱心網友回復:
這個好像沒有用到icmp??根本沒有資料報的發送接收決議,而且我只是要把上面的代碼加上圖形界面。。。
uj5u.com熱心網友回復:
我知道ARP比較快,但是程式要求就是icmp,而且需要圖形界面,不是我能決定的
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/132525.html
標籤:網絡編程
