单线程的 端口扫描 奇怪现象

IvanForSun 2008-12-02 12:19:59
采用的方式是,新开一个线程,用afxbeginthread(),然后根据IP段和端口范围进行connect扫描,每次都新建一个stream套接字,套接字用异步选择(WSAAsyncSelect)的方式,遇到是问题是,扫描执行完几次就停下了,并没有完全扫描.代码如下:

for (DWORD dwIP = pInfo->startIP ; dwIP <= pInfo->endIP ; dwIP++){ //IP段
for (DWORD dwPort = pInfo->startPort ; dwPort <= pInfo->endPort ; dwPort++){ //端口
SOCKET socket_scan = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //建套接字
if (INVALID_SOCKET == socket_scan){
AfxMessageBox("创建套接字失败!");
return 0;
}
if (SOCKET_ERROR == WSAAsyncSelect(socket_scan,pDlg->GetSafeHwnd(),WM_SOCKETEVENT_SCAN,FD_CONNECT)){ //异步选择
AfxMessageBox("异步选择失败!");
return 0;
}
sockaddr_in addr;
ZeroMemory(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons((WORD)dwPort);
addr.sin_addr.s_addr = htonl(dwIP);
connect(socket_scan,(sockaddr*)&addr,sizeof(sockaddr)); //连接,不能全部执行
}
}


目前,通过单步调试(在connect处设断点),发现在目标是1000次的扫描中,有时执行2次就退出,有时执行几十次,这是什么原因?望指教
执行IP是172.80.1.135 -172.80.1.135(单机扫描) 端口是0-1000
...全文
115 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Formular1 2008-12-05
  • 打赏
  • 举报
回复
所有的 if 都改用 信号灯 sephermore 和超时退出。
退出时做记录,看看什么原因。
这种有时2次,有时100多次的原因多半是线程同步问题,connect 这些函数都不是立刻成功的,
要等待。
kasdmn 2008-12-05
  • 打赏
  • 举报
回复
//核心线程体
UINT threadA(LPVOID pParam) //此线程处理每个端口的检测
{
struct thread *threada=(struct thread*)pParam; //获取传入的参数(IP和窗口句柄)
//在内部重新打开互斥量,互斥量已经由threadM创建
HANDLE hCounterIn=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"sam sp 44");
//等待此互斥量为signaled状态后操作临界资源(m_nCounter)
WaitForSingleObject(hCounterIn,INFINITE);
UINT v=m_nCounter; //设定本线程要检测的端口值为m_nCounter,存入变量v
m_nCounter++; //设定下一线程要检测的端口值,m_nCounter加1
ReleaseMutex(hCounterIn); //释放互斥量
CloseHandle(hCounterIn); //关闭互斥量

struct sockaddr_in sin; //声明变量存储套接字地址

SOCKET sd; //声明套接字变量
int IpPort; //声明存储端口的变量
char IpAddr[16]; //存储要连接的对方的IP地址
strcpy(IpAddr,threada->ip); //将threada->ip中存储的对方的IP地址拷贝进IpAddr
IpPort=v; //初始化要连接的对方的端口为v

//建立一个本地套接字,设定为流式套接字,应用ip协议
//判断是否创建失败
if ((sd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET)
{
printf("Create socket error!"); //显示失败提示信息
return 1;
}

//连接到对方的主机iP
sin.sin_family=AF_INET; //设定地址家族规范
sin.sin_addr.s_addr=inet_addr(IpAddr); //转换地址形式并且存入sin中地址分量
sin.sin_port=htons((short)IpPort); //将IpPort值转换其字节序为网络字节序,存入sin_port分量

//用connect命令检测对方端口,根据返回值判断是否连接成功
if (connect (sd, (struct sockaddr *)&sin, sizeof (sin)) == SOCKET_ERROR)
{
printf("Connect the remote IP error!"); //若不成功,则提示相应信息
closesocket (sd); //关闭本地套接字
return 1;
}
else //若连接成功,向当前窗口发送一个消息用于在列表中输出,参数为v(端口值)
{
::PostMessage(threada->m_hwnd,WM_USER_PRINT_START,v,0);
}

closesocket (sd); //关闭本地套接字
AfxEndThread(0); //结束当前线程,设定返回值为0
return 0;
}
zhoujianhei 2008-12-03
  • 打赏
  • 举报
回复
WSAAsyncSelect 对应 WSAConnect
select 对应 connect

IvanForSun 2008-12-03
  • 打赏
  • 举报
回复
现在问题的焦点 我感觉是 connect() WSAAsyncSelect() 的关系了
IvanForSun 2008-12-03
  • 打赏
  • 举报
回复
for (DWORD dwIP = pInfo->startIP ; dwIP <= pInfo->endIP ; dwIP++){ //IP段
for (DWORD dwPort = pInfo->startPort ; dwPort <= pInfo->endPort ; dwPort++){ //端口
................
................
}

目前的情况是当2个循环退出后,套接字的connect也不执行了,是不是扫描的问题不应该用异步选择,还是应该用线程,当前我查到的资料几乎都是用多线程的方式进行端口扫描..........
IvanForSun 2008-12-03
  • 打赏
  • 举报
回复
我用的是异步选择 WSAASyncSelect(),我试一下wwwllg说的重叠套接字试试
cnzdgs 2008-12-02
  • 打赏
  • 举报
回复
“退出”是什么意思?
hackwolfoscar 2008-12-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 WinEggDrop 的回复:]
引用楼主 IvanForSun 的帖子:
采用的方式是,新开一个线程,用afxbeginthread(),然后根据IP段和端口范围进行connect扫描,每次都新建一个stream套接字,套接字用异步选择(WSAAsyncSelect)的方式,遇到是问题是,扫描执行完几次就停下了,并没有完全扫描.代码如下:

C/C++ code
for (DWORD dwIP = pInfo->startIP ; dwIP <= pInfo->endIP ; dwIP++){ //IP段
for (DWORD dwPort = pInfo->startPort ; dwPo…
[/Quote]

如果真是这样说的,设置个超时时间看看
UDX协议 2008-12-02
  • 打赏
  • 举报
回复
SOCKET socket_scan = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //建套接字
要用重叠套接字。

这样才可以很快联接完成。
猞猁狲 2008-12-02
  • 打赏
  • 举报
回复
用FD_SET设置下事件试试
WinEggDrop 2008-12-02
  • 打赏
  • 举报
回复
[Quote=引用楼主 IvanForSun 的帖子:]
采用的方式是,新开一个线程,用afxbeginthread(),然后根据IP段和端口范围进行connect扫描,每次都新建一个stream套接字,套接字用异步选择(WSAAsyncSelect)的方式,遇到是问题是,扫描执行完几次就停下了,并没有完全扫描.代码如下:

C/C++ code
for (DWORD dwIP = pInfo->startIP ; dwIP <= pInfo->endIP ; dwIP++){ //IP段
for (DWORD dwPort = pInfo->startPort ; dwPort <= pInfo->endPort ; dwPort+…
[/Quote]

connect执行后,不一定马上能连接上,如果不在线的IP,超时是近20秒.这个时间内你的两个循环都完成的话,程序自然就退出,这有什么好奇怪的,这是正常的.你要程序不退出,就要判断所有connect()都被执行完后(WM_SOCKETEVENT_SCAN接收到所有connect返回的结果,成功还是失败)才让程序退出.
WinEggDrop 2008-12-02
  • 打赏
  • 举报
回复
[Quote=引用楼主 IvanForSun 的帖子:]
采用的方式是,新开一个线程,用afxbeginthread(),然后根据IP段和端口范围进行connect扫描,每次都新建一个stream套接字,套接字用异步选择(WSAAsyncSelect)的方式,遇到是问题是,扫描执行完几次就停下了,并没有完全扫描.代码如下:

C/C++ code
for (DWORD dwIP = pInfo->startIP ; dwIP <= pInfo->endIP ; dwIP++){ //IP段
for (DWORD dwPort = pInfo->startPort ; dwPort <= pInfo->endPort ; dwPort+…
[/Quote]

connect执行后,不一定马上能连接上,如果不在线的IP,超时是近20秒.这个时间内你的两个循环都完成的话,程序自然就退出,这有什么好奇怪的,这是正常的.你要程序不退出,就要判断所有connect()都被执行完后(WM_SOCKETEVENT_SCAN接收到所有connect返回的结果,成功还是失败)才让程序退出.

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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