一个很笨的多线程扫描程序,大家顺便帮忙看看怎么优化
从端口 1 开始 connect ,共起了
#include "winsock2.h"
#include "ws2tcpip.h"
#include "stdlib.h"
#include "stdio.h"
#include "windows.h"int getport(u_short *);
unsigned long __stdcall scanport(void *);
static int threadcount=0;
int main(){
WSADATA wsd;
DWORD newthread; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
::MessageBox(NULL,"socket 失败 ","sorry!",MB_OK);
}
for(int i=0;i<300;i++){
::CreateThread (NULL,0,scanport,NULL,0,&newthread);
threadcount++;
}
while(threadcount)::Sleep(100);
return 0;
}
unsigned long __stdcall scanport(void *){
u_short port;
SOCKET s;
struct sockaddr_in sin;
char portstr[7]; sin.sin_family =AF_INET;
sin.sin_addr.s_addr =inet_addr("192.168.0.1"); while(getport(&port)){
s = socket(AF_INET, SOCK_STREAM, 0);
// itoa(port,portstr,10);
// printf("\n\tport %d:",port);
sin.sin_port =htons(port);
if(!connect(s,(sockaddr *)&sin,sizeof(sin)))printf("\n\ta server is running on port:%d",port);
closesocket(s);
}
threadcount--;
return 0;
}int getport(u_short * port){
static u_short currentport=1;
currentport++;
// printf("\nport %d",currentport);
if(currentport>65534)//65535
return 0;
else
(*port)=currentport;
return 1;
}
从端口 1 开始 connect ,共起了
#include "winsock2.h"
#include "ws2tcpip.h"
#include "stdlib.h"
#include "stdio.h"
#include "windows.h"int getport(u_short *);
unsigned long __stdcall scanport(void *);
static int threadcount=0;
int main(){
WSADATA wsd;
DWORD newthread; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
::MessageBox(NULL,"socket 失败 ","sorry!",MB_OK);
}
for(int i=0;i<300;i++){
::CreateThread (NULL,0,scanport,NULL,0,&newthread);
threadcount++;
}
while(threadcount)::Sleep(100);
return 0;
}
unsigned long __stdcall scanport(void *){
u_short port;
SOCKET s;
struct sockaddr_in sin;
char portstr[7]; sin.sin_family =AF_INET;
sin.sin_addr.s_addr =inet_addr("192.168.0.1"); while(getport(&port)){
s = socket(AF_INET, SOCK_STREAM, 0);
// itoa(port,portstr,10);
// printf("\n\tport %d:",port);
sin.sin_port =htons(port);
if(!connect(s,(sockaddr *)&sin,sizeof(sin)))printf("\n\ta server is running on port:%d",port);
closesocket(s);
}
threadcount--;
return 0;
}int getport(u_short * port){
static u_short currentport=1;
currentport++;
// printf("\nport %d",currentport);
if(currentport>65534)//65535
return 0;
else
(*port)=currentport;
return 1;
}
他们会处理一些 标准 c 库函数的上下文。
start
下面是关于 _beginthreadex 的一些要点:
-- 每个线程均获得由 c/c++ 运行期库的堆栈分配的自己的 tiddata 内存结构。
-- 传递给_beginthreadex 的线程函数地址保存在 tiddata 内存块中。传递给该函数的参数也
保存在该数据块中。
-- _beginthreadex 确实从内部调用了 CreateThread,因为这是操作系统了解如何创建线程
的唯一方法
-- 当调用 CreateThread 是,他被告知通过调用 _threadstartex 而不是 pfnStartAddr
来启动执行新线程。还有,传递给线程的参数是 tiddata 数据结构而不是 pvParam 的地址
-- 如果一切顺利,就会象 CreateThread 那样返回线程句柄,失败 返回 nullend标准 c 运行期库远远早于线程问世,所以在多线程程序上运行的时候会有一些问题,比如 errno
一个线程设为 1 后正巧被中断,第二个线程这是把 errno 设为 3 ,当第一个线程恢复运行时检查errno 就出问题了。 tiddata 数据结构和 _beginthreadex 就是为解决这个问题产生的。_endthread 则完成对应的清除工作。当然,关于这个问题还有很多内容,我手工输入太慢了。详细可以参考《windows 核心编程》----非常好的一本书
//---------- g_var
UINT ThreadProc(LPVOID pParam);
CEvent g_eBusy;
BOOL CPicFileDlg::OnInitDialog()
{
CFileDialog::OnInitDialog();
// TODO: Add extra initialization here
SetTimer(1, 500, NULL);
g_eBusy.SetEvent(); return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
UINT ThreadProc(LPVOID pParam)
{
g_eBusy.ResetEvent(); CWnd hWnd;
hWnd.Attach((HWND)pParam);
ASSERT(hWnd); CRect m_Rect;
CDC *m_pDC;
hWnd.GetClientRect(&m_Rect);
m_pDC=hWnd.GetDC(); PreViewPic(g_sFileName, m_pDC, m_Rect);
hWnd.Detach();
g_eBusy.SetEvent();
return 0;
}
void CPicFileDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString sName=GetFileName(), sExt=GetFileExt(); if (sName=="" && sExt.CompareNoCase("bmp") && sExt.CompareNoCase("gif") && sExt.CompareNoCase("jpg"))
return; if (g_sFileName.CompareNoCase(sName) && WaitForSingleObject(g_eBusy, 0)==WAIT_OBJECT_0)
{
g_sFileName=sName;
AfxBeginThread(ThreadProc,m_hPicView.GetSafeHwnd());
}
CFileDialog::OnTimer(nIDEvent);
}void CPicFileDlg::OnDestroy()
{
// TODO: Add your message handler code here
KillTimer(1);
WaitForSingleObject(g_eBusy, INFINITE); CFileDialog::OnDestroy();
}