📄 searchhostdlg.cpp
字号:
// SearchHostDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PeerYouC.h"
#include "SearchHostDlg.h"
#include "Peersocket.h"
#include "command.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HANDLE hThread;
HANDLE hThreadExit;
PARAM paa;
/////////////////////////////////////////////////////////////////////////////
// CSearchHostDlg dialog
CSearchHostDlg::CSearchHostDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSearchHostDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSearchHostDlg)
//}}AFX_DATA_INIT
bExit=false;
bRealExit=false;
}
void CSearchHostDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSearchHostDlg)
DDX_Control(pDX, IDC_PROGRESS, m_Process);
DDX_Control(pDX, IDC_LIST_HOST, m_listHosts);
DDX_Control(pDX, IDC_IPADDRESS_SECOND, m_HostAddrSecond);
DDX_Control(pDX, IDC_IPADDRESS_FIRST, m_HostAddrFirst);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSearchHostDlg, CDialog)
//{{AFX_MSG_MAP(CSearchHostDlg)
ON_BN_CLICKED(IDC_EXIT, OnExit)
ON_BN_CLICKED(IDC_SEARCH, OnSearch)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_STOP, OnStop)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSearchHostDlg message handlers
void CSearchHostDlg::OnExit()
{
// TODO: Add your control notification handler code here
if(bRealExit)
SendMessage(WM_CLOSE);
else
MessageBox("需要先中止搜索");
}
BOOL CSearchHostDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
bExit=false;
CRect rtClient;
m_listHosts.GetClientRect(rtClient);
LVCOLUMN colinfo;
memset(&colinfo,0,sizeof(colinfo));
colinfo.mask=LVCF_WIDTH|LVCF_FMT|LVCF_TEXT;
colinfo.fmt=LVCFMT_CENTER;
colinfo.cchTextMax=255;
colinfo.cx=rtClient.Width()-40;
colinfo.pszText="服务器地址";
m_listHosts.InsertColumn(0,&colinfo);
colinfo.cx=40;
colinfo.pszText="状态";
m_listHosts.InsertColumn(1,&colinfo);
if(!CreateEvent(NULL,true,false,NULL))
return false;
ResetEvent(hThreadExit);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CSearchHostDlg::OnSearch()
{
// TODO: Add your control notification handler code here
CMainFrame* wMainFrame=(CMainFrame*)AfxGetApp()->GetMainWnd();
CTreeCtrl& tree=wMainFrame->m_pTreeHost->GetTreeCtrl();
if(!tree.DeleteAllItems())
ASSERT(false);
if(!m_listHosts.DeleteAllItems())
ASSERT(false);
CButton* button=(CButton*)GetDlgItem(IDC_SEARCH);
if(button)
button->EnableWindow(false);
CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE);
if(sta)
sta->ShowWindow(SW_HIDE);
/////////////////////////
CString addrstart,addrend;
m_HostAddrFirst.GetWindowText(addrstart);
m_HostAddrSecond.GetWindowText(addrend);
if(addrstart>addrend)
{
MessageBox("第二个地址应大于第一个地址");
return ;
}
ULONG lStart=ntohl(inet_addr(addrstart));
ULONG lEnd=ntohl(inet_addr(addrend));
ULONG lSub=lEnd-lStart+1; //一共有多少个地址
m_Process.SetRange32(0,lSub);
m_Process.ShowWindow(SW_SHOW);
UINT ThreadID;
HTREEITEM item=tree.InsertItem( "PeerYou服务器",0,0);
paa.dlg=(void*)this;
paa.count=lSub;
paa.now=lStart;
if((hThread=BeginThread(SearchFun,&paa,&ThreadID))<=0)
{
MessageBox("创建搜索线程失败");
if(!tree.DeleteAllItems())
ASSERT(false);
return;
}
tree.Expand(item,TVE_EXPAND);
}
UINT WINAPI SearchFun(PVOID param)
{
PARAM npa;
memcpy(&npa,param,sizeof(PARAM));
WSAEVENT event=WSACreateEvent();
DWORD add;
SOCKET sock;
DWORD ret;
int nhost=0;
int index;
CSearchHostDlg* dlg=(CSearchHostDlg*)npa.dlg;
CMainFrame *mframe=(CMainFrame*)AfxGetApp()->GetMainWnd();
CTreeCtrl& tree=mframe->m_pTreeHost->GetTreeCtrl();
HTREEITEM item=tree.GetRootItem();
HTREEITEM item2;
SYSTEMINIT si;
COMMAND com;
char address[16];
for(int i=0;i<npa.count;i++)
{
if(dlg->bExit)
{
dlg->bExit=false;
closesocket(sock);
WSACloseEvent(event);
SetEvent(hThreadExit);
return 0;
}
PeerCreateSocket(&sock,PEER_STREAM);
add=npa.now+i;
add=htonl(add);
in_addr ina;
memset(&ina,0,sizeof(ina));
ina.S_un.S_addr=add;
strcpy(address,inet_ntoa(ina));
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
PeerConnectSocket(sock,address,7788);
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = 2; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret >0 )
{
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (sock);
continue;
}
index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address);
dlg->m_listHosts.SetItemText(index,1,"在线");
item2=tree.InsertItem(address,1,1,item);
memset(&com,0,sizeof(com));
com.CommandID=PEER_SYSTEM_INIT;
com.DataSize=0;
if(PeerSendDataS(sock,(char*)&com,sizeof(com),&ret,event)&&ret==sizeof(com))
{
if(PeerRecvDataS(sock,(char*)&si,sizeof(si),&ret,event)&&ret==sizeof(si))
{
tree.InsertItem(si.computer,2,2,item2);
tree.InsertItem(si.user,3,3,item2);
tree.InsertItem(si.os,4,4,item2);
tree.InsertItem(si.processor,5,5,item2);
tree.InsertItem(si.mem,6,6,item2);
tree.InsertItem(si.disk,7,7,item2);
}
}
tree.RedrawWindow();
nhost++;
}
else
{
index=dlg->m_listHosts.InsertItem(dlg->m_listHosts.GetItemCount(),address);
dlg->m_listHosts.SetItemText(index,1,"未通");
}
dlg->m_Process.SetPos(i+1);
closesocket(sock);
}
WSACloseEvent(event);
dlg->m_Process.ShowWindow(SW_HIDE);
CButton* button=(CButton*)dlg->GetDlgItem(IDC_SEARCH);
if(button)
button->EnableWindow(true);
CStatic* sta=(CStatic*)dlg->GetDlgItem(IDC_MESSAGE);
if(sta)
{
sta->ShowWindow(SW_SHOW);
char msg[100];
sprintf(msg,"查找已经完成,%d个主机在线!",nhost);
sta->SetWindowText(msg);
}
if(nhost==0)
tree.DeleteAllItems();
dlg->bExit=false;
return 0;
}
void CSearchHostDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CDialog::OnClose();
}
void CSearchHostDlg::OnStop()
{
// TODO: Add your control notification handler code here
UpdateData();
bExit=true;
bRealExit=true;
DWORD n = WaitForSingleObject(hThreadExit,60000);
Sleep(500);
if(n==WAIT_TIMEOUT)
{
TerminateThread(hThread,0);
}
CloseHandle(hThreadExit);
CloseHandle(hThread);
CStatic* sta=(CStatic*)GetDlgItem(IDC_MESSAGE);
m_Process.ShowWindow(SW_HIDE);
CButton* button=(CButton*)GetDlgItem(IDC_SEARCH);
button->EnableWindow();
if(sta)
{
sta->ShowWindow(SW_SHOW);
sta->SetWindowText("中止搜索主机!");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -