先前写了一个单线程的扫描端口的程序,发现扫描端口太慢,
然后自己试着写多线程下的扫描程序,以前没写过多线程的程序,写成这样,
哪位大侠帮我改改错,给我点意见,谢谢了!!!#include <iostream>
#include <Winsock2.h>
#include <string>
#pragma comment(lib,"ws2_32.lib")
using namespace std;int i;
int PortEnd;
string IPstr;
CRITICAL_SECTION  g_sect;
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
while(1)
{
EnterCriticalSection(&g_sect);//获得临界区对象所有权
Sleep(10);
if(i<=PortEnd)
{
Sleep(10);
SOCKET testsocket;
int iopenedport = 0;
struct sockaddr_in target_addr; cout << "正在建立socket............." << endl;
if ((testsocket=socket (AF_INET,SOCK_STREAM,0) ) == INVALID_SOCKET)
{
cout << "Socket建立失败!" << endl;
exit(0);
}
target_addr.sin_family = AF_INET;
target_addr.sin_port = htons(i);
target_addr.sin_addr.s_addr = inet_addr (IPstr.c_str());
cout << "正在扫描端口:" << i << endl;
if (connect (testsocket, (struct sockaddr *) &target_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
cout << "端口" << i << "关闭!" << endl;
else
{
iopenedport++;
cout << "端口" << i << "开放\n" << endl;
}
i++;
LeaveCriticalSection(&g_sect);//释放临界区对象所有权
}
else
{
LeaveCriticalSection(&g_sect);//释放临界区对象所有权
break;
}
}
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
while(1)
{
EnterCriticalSection(&g_sect);//获得临界区对象所有权
Sleep(10);
if(i<=PortEnd)
{
Sleep(10);
SOCKET testsocket;
int iopenedport = 0;
struct sockaddr_in target_addr; cout << "正在建立socket............." << endl;
if ((testsocket=socket (AF_INET,SOCK_STREAM,0) ) == INVALID_SOCKET)
{
cout << "Socket建立失败!" << endl;
exit(0);
}
target_addr.sin_family = AF_INET;
target_addr.sin_port = htons(i);
target_addr.sin_addr.s_addr = inet_addr (IPstr.c_str());
cout << "正在扫描端口:" << i << endl;
if (connect (testsocket, (struct sockaddr *) &target_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
cout << "端口" << i << "关闭!" << endl;
else
{
iopenedport++;
cout << "端口" << i << "开放\n" << endl;
}
i++;
LeaveCriticalSection(&g_sect);//释放临界区对象所有权
}
else
{
LeaveCriticalSection(&g_sect);//释放临界区对象所有权
break;
}
}
return 0;
}int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1,1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
cerr<<"WSAStartup error!"<<err<<endl;
return 1;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{ WSACleanup();
return 1; 
}
int iportFrom,iportTo;
string str;
cout<<"Please input IP: ";
cin>>str;
cout<<"Please input 开始端口: ";
cin>>iportFrom;
cout<<"Please input 截止端口: ";
cin>>iportTo; i=iportFrom;
PortEnd=iportTo;
IPstr=str; DWORD IDThread1;
DWORD IDThread2; HANDLE hthread1;
HANDLE hthread2;
hthread1=CreateThread(NULL,0,ThreadProc1,NULL,0,&IDThread1);
hthread2=CreateThread(NULL,0,ThreadProc2,NULL,0,&IDThread2);
CloseHandle(hthread1);
CloseHandle(hthread2);
cout<<IDThread1<<endl<<IDThread2<<endl; InitializeCriticalSection(&g_sect); //初始化临界区对象
Sleep(10000); DeleteCriticalSection(&g_sect); //释放临界区对象 return 0;
}
谢谢了!!!!!

解决方案 »

  1.   

    这个代码似曾相识啊 InitializeCriticalSection(&g_sect);     //这个应该先初始化
     
    hthread1=CreateThread(NULL,0,ThreadProc1,NULL,0,&IDThread1);
        hthread2=CreateThread(NULL,0,ThreadProc2,NULL,0,&IDThread2);
        CloseHandle(hthread1);
        CloseHandle(hthread2);
      

  2.   

    ThreadProc一个就够了,都是一样的代码,写这么多干吗
      

  3.   

    给你一个代码,在你的基础上改的
    #include <stdlib.h>
    #include <stdio.h>
    #include <Winsock2.h>#pragma comment(lib,"ws2_32.lib")typedef struct PortInfo
    {
    char  ip[32];
    short fromPort;
    short toPort;
    }PORTINFO,*PPORTINFO;
    DWORD WINAPI ThreadProc(LPVOID lpParam)
    {
    PPORTINFO portinfo=(PPORTINFO)lpParam; if(portinfo==NULL)
    {
    return -1;
    } short fromPort=portinfo->fromPort;
    short toPort=portinfo->toPort; while(fromPort<=toPort)
    {
    SOCKET testsocket;
    struct sockaddr_in target_addr; printf("正在建立socket.............\n");
    if ((testsocket=socket (AF_INET,SOCK_STREAM,0) ) == INVALID_SOCKET)
    {
    printf("Socket建立失败!\n");
    return 0;
    } target_addr.sin_family = AF_INET;
    target_addr.sin_port = htons(fromPort);
    target_addr.sin_addr.s_addr = inet_addr (portinfo->ip);

    printf("正在扫描端口 %s:%u \n",portinfo->ip,fromPort); if (connect (testsocket, (struct sockaddr *) &target_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
    {
    printf("端口 %u 关闭!\n",fromPort);
    }
    else
    {
    printf("端口 %u 开放!\n",fromPort);
    } fromPort++; Sleep(20);
    } return 0;
    }int _tmain(int argc, _TCHAR* argv[])
    {
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
        wVersionRequested = MAKEWORD( 2,2 );    err = WSAStartup( wVersionRequested, &wsaData );    if ( err != 0 )
        {
            printf("WSAStartup error!\n");
            return 1;
        }    if ( LOBYTE( wsaData.wVersion ) != 2 ||
            HIBYTE( wsaData.wVersion ) != 2 )
        {        WSACleanup();
            return 1; 
        }    short iportFrom,iportTo;
    char IPstr[32]; memset(IPstr,0,sizeof(IPstr));    printf("Please input IP:\n");
        scanf("%16s",IPstr);    printf("Please input 开始端口:");
        scanf("%hd",&iportFrom);    printf("Please input 截止端口:");
        scanf("%hd",&iportTo); if(iportTo<iportFrom||iportTo<=0)
    {
    printf("端口号要大于0,并且截止端口要大于或者等于开始端口!\n");
    return -1;
    } int tmp=(iportTo-iportFrom)/2; PORTINFO portinfo1,portinfo2; strcpy(portinfo1.ip,IPstr);
    portinfo1.fromPort=iportFrom;
    portinfo1.toPort=iportFrom+tmp;

    strcpy(portinfo2.ip,IPstr);
    portinfo2.fromPort=portinfo1.toPort+1;
    portinfo2.toPort=iportTo;    DWORD IDThread1;
        DWORD IDThread2;    HANDLE hthread[2];    hthread[0]=CreateThread(NULL,0,ThreadProc,&portinfo1,0,&IDThread1);
        hthread[1]=CreateThread(NULL,0,ThreadProc,&portinfo2,0,&IDThread2); WaitForMultipleObjects(2,hthread,TRUE,INFINITE);
       
    CloseHandle(hthread[0]);
        CloseHandle(hthread[1]);    return 0;
    }
      

  4.   

    谢谢我笨善良啦!
    刚又写了一个,但运行的时候只是出现最后一个端口的结果,找了半天找不着错误#include "stdafx.h"
    #include <stdio.h>
    #include <Winsock2.h>
    #include <stdlib.h>
    #pragma comment(lib,"ws2_32.lib")typedef struct sock_information
    {
    char ip[17];
    int port;
    }sockinfo;DWORD WINAPI  ThreadProc(LPVOID laParam)
    {
    sockinfo sf=*(sockinfo*)laParam; SOCKET sockcon=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sockcon==INVALID_SOCKET)
    {
    printf("Error at socket(): %ld\n", WSAGetLastError());
    return 1;
    } sockaddr_in sacon;
    sacon.sin_addr.S_un.S_addr=inet_addr(sf.ip);
    sacon.sin_family=AF_INET;
    sacon.sin_port=htons(sf.port); if(connect(sockcon,(sockaddr*)&sacon,sizeof(sockaddr)==SOCKET_ERROR))
    {
    printf("Port %4d is closed!\n",sf.port);
    }
    else
    {
    printf("Port %4d is open!\n",sf.port);
    }
    closesocket(sockcon); return 0;
    }
    int main()
    {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 )
    return 1;
    if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) 
    {
    WSACleanup();
    return 1; 
    }
    char str_ip[17];
    memset(str_ip,0,17);
    printf("Please input the IP:");
    scanf("%s",str_ip);
    fflush(stdin); int port_from;
    printf("Please input the port_from:");
    scanf("%d",&port_from);
    fflush(stdin); int port_to;
    printf("Please input the port_to:");
    scanf("%d",&port_to); int thread_sum=port_to-port_from+1; //得到要扫描的端口数目
    HANDLE* hthread=new HANDLE[thread_sum];
    DWORD threadID; sockinfo sf;
    strcpy(sf.ip,str_ip);
    for(int i=0;i<thread_sum;i++)
    {
    sf.port=port_from+i;
    hthread[i]=CreateThread(NULL,0,ThreadProc,(LPVOID)&sf,0,&threadID);
    }
    ::WaitForMultipleObjects(thread_sum,hthread,FALSE,INFINITE);
    for(int i=0;i<thread_sum;i++)
    {
    CloseHandle(hthread[i]);
    }
    delete []hthread;
    WSACleanup();
    return 0;
    }
      

  5.   

    WaitForMultipleObjects最多只能等待64个句柄,多了就出问题了,
    而且你也用不着1个端口对应一个线程,一般一两百个线程就行了WaitForMultipleObjects(thread_sum,hthread,FALSE,INFINITE);
    可以改为,目的就是等待所有线程退出
    for(int i=0;i<thread_sum;i++)
        {
           WaitForSingleObject(hthread[i],INFINITE);
        }
      

  6.   


    #include <stdio.h>
    #include <Winsock2.h>
    #include <stdlib.h>
    #pragma comment(lib,"ws2_32.lib")typedef struct sock_information
    {
    char ip[17];
    int port;
    }sockinfo;DWORD WINAPI  ThreadProc(LPVOID laParam)
    {
    sockinfo sf=*(sockinfo*)laParam; SOCKET sockcon=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sockcon==INVALID_SOCKET)
    {
    printf("Error at socket(): %ld\n", WSAGetLastError());
    return 1;
    } sockaddr_in sacon;
    sacon.sin_addr.S_un.S_addr=inet_addr(sf.ip);
    sacon.sin_family=AF_INET;
    sacon.sin_port=htons(sf.port); if(connect(sockcon,(sockaddr*)&sacon,sizeof(sockaddr)==SOCKET_ERROR))
    {
    printf("Port %4d is closed!\n",sf.port);
    }
    else
    {
    printf("Port %4d is open!\n",sf.port);
    }
    closesocket(sockcon); return 0;
    }
    int main()
    {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 )
    return 1;
    if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) 
    {
    WSACleanup();
    return 1; 
    }
    char str_ip[17];
    memset(str_ip,0,17);
    printf("Please input the IP:");
    scanf("%s",str_ip);
    fflush(stdin); int port_from;
    printf("Please input the port_from:");
    scanf("%d",&port_from);
    fflush(stdin); int port_to;
    printf("Please input the port_to:");
    scanf("%d",&port_to); int thread_sum=port_to-port_from+1; //得到要扫描的端口数目
    HANDLE* hthread=new HANDLE[thread_sum];
    DWORD threadID; sockinfo sf;
    strcpy(sf.ip,str_ip);
    for(int i=0;i<thread_sum;i++)
    {
    sf.port=port_from+i;
    hthread[i]=CreateThread(NULL,0,ThreadProc,(LPVOID)&sf,0,&threadID);
    }
    for(int i=0;i<thread_sum;i++)
    {
    ::WaitForSingleObject(hthread[i],INFINITE);
    }
    //::WaitForMultipleObjects(thread_sum,hthread,FALSE,INFINITE);
    for(int i=0;i<thread_sum;i++)
    {
    CloseHandle(hthread[i]);
    }
    delete []hthread;
    WSACleanup();
    return 0;
    }
    改了还是有错,程序最后只扫描了最后一个端口,为什么啊,找不出错,帮帮忙吧大家!
      

  7.   

    sockinfo sf;
        strcpy(sf.ip,str_ip);
        for(int i=0;i<thread_sum;i++)
        {
            sf.port=port_from+i;
            hthread[i]=CreateThread(NULL,0,ThreadProc,(LPVOID)&sf,0,&threadID);
        }你这里都是用的一个sf当然就是最后一个端口几个线程就用几个sf给你一个我写的改进版的
    #include <stdlib.h>
    #include <stdio.h>
    #include <Winsock2.h>#pragma comment(lib,"ws2_32.lib")typedef struct PortInfo
    {
    char  ip[32];
    short fromPort;
    short toPort;
    short *openedPort;
    short openedPortCount;
    }PORTINFO,*PPORTINFO;
    DWORD WINAPI ThreadProc(LPVOID lpParam)
    {
    PPORTINFO portinfo=(PPORTINFO)lpParam; if(portinfo==NULL)
    {
    return -1;
    } short fromPort=portinfo->fromPort;
    short toPort=portinfo->toPort; while(fromPort<=toPort)
    {
    SOCKET testsocket;
    struct sockaddr_in target_addr; printf("正在建立socket.............\n");
    if ((testsocket=socket (AF_INET,SOCK_STREAM,0) ) == INVALID_SOCKET)
    {
    printf("Socket建立失败!\n");
    return 0;
    } target_addr.sin_family = AF_INET;
    target_addr.sin_port = htons(fromPort);
    target_addr.sin_addr.s_addr = inet_addr (portinfo->ip);

    printf("正在扫描端口 %s:%u \n",portinfo->ip,fromPort); if (connect (testsocket, (struct sockaddr *) &target_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
    {
    printf("端口 %u 关闭!\n",fromPort);
    }
    else
    {
    portinfo->openedPort[portinfo->openedPortCount]=fromPort;
    portinfo->openedPortCount++;
    printf("端口 %u 开放!\n",fromPort);
    } closesocket(testsocket); fromPort++; //Sleep(20);
    } return 0;
    }#define THREAD_COUNT 100int _tmain(int argc, _TCHAR* argv[])
    {
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
        wVersionRequested = MAKEWORD( 2,2 );    err = WSAStartup( wVersionRequested, &wsaData );    if ( err != 0 )
        {
            printf("WSAStartup error!\n");
            return 1;
        }    if ( LOBYTE( wsaData.wVersion ) != 2 ||
            HIBYTE( wsaData.wVersion ) != 2 )
        {        WSACleanup();
            return 1; 
        }    short iportFrom,iportTo;
    char IPstr[32]; memset(IPstr,0,sizeof(IPstr));    printf("Please input IP:\n");
        scanf("%16s",IPstr);    printf("Please input 开始端口:");
        scanf("%hd",&iportFrom);    printf("Please input 截止端口:");
        scanf("%hd",&iportTo); if(iportTo<iportFrom||iportFrom<=0||iportTo<=0)
    {
    printf("端口号要大于0,并且截止端口要大于或者等于开始端口!\n");
    return -1;
    } int threadCount=THREAD_COUNT; int tmp=(iportTo-iportFrom)/THREAD_COUNT;
    if(tmp==0)
    {
    tmp=1;
    threadCount=iportTo-iportFrom+1;
    } //int resver=(iportTo-iportFrom)%5;
    PPORTINFO portinfo= new PORTINFO[threadCount]; //PORTINFO portinfo[THREAD_COUNT];
        HANDLE* hthread=new HANDLE[threadCount];
        DWORD IDThread; DWORD beginTime=GetTickCount(); for(int i=0;i<threadCount-1;i++)
    {
    strcpy(portinfo[i].ip,IPstr);
    portinfo[i].fromPort=iportFrom+i*tmp;
    portinfo[i].toPort=portinfo[i].fromPort+tmp-1;
    portinfo[i].openedPortCount=0;
    portinfo[i].openedPort = new short[tmp];

    hthread[i]=CreateThread(NULL,0,ThreadProc,&portinfo[i],0,&IDThread);
    }

    strcpy(portinfo[threadCount-1].ip,IPstr);
    portinfo[threadCount-1].fromPort=iportFrom+(threadCount-1)*tmp;
    portinfo[threadCount-1].toPort=iportTo;
    portinfo[threadCount-1].openedPortCount=0;
    portinfo[threadCount-1].openedPort = new short[iportTo-portinfo[threadCount-1].fromPort+1];

    hthread[threadCount-1]=CreateThread(NULL,0,ThreadProc,&portinfo[threadCount-1],0,&IDThread); for(int i=0;i<threadCount;i++)
    {
    WaitForSingleObject(hthread[i],INFINITE);
    } for(int i=0;i<threadCount;i++)
    {
    CloseHandle(hthread[i]); } DWORD endTime=GetTickCount(); printf("开始时间:%d\n结束时间:%d\n花费时间:%d\n",beginTime,endTime,endTime-beginTime); for(int i=0;i<threadCount;i++)
    {
    for(int j=0;j<portinfo[i].openedPortCount;j++)
    {
    printf("IP:%s 开放的端口:%hd\n",portinfo[i].ip,portinfo[i].openedPort[j]);
    }
    } for(int i=0;i<threadCount;i++)
    {
    delete[] portinfo[i].openedPort;
    } delete[] portinfo;
    delete[] hthread;    return 0;
    }
      

  8.   

    class ConfigItem
    {
    public:
    ConfigItem(){};
    ConfigItem(string user, string pwd, string serv1, string port1, string serv2, string port2, string role); string strUser;
    string strPwd;
    string strLoginServerIP;
    string strLoginServerPort;
    string strGameServerIP;
    string strGameServerPort;
    string strRole;
    int iStatus;
    int iFailedTimes;

    CTime lastGameTime; //上一次发送保持游戏服务器连接指令的时间
    CTime lastPartyTime; // 上一次发送保持频道服务器连接指令的时间
    CTime lastMsgTime; // 上一次发送喊话指令的时间 unsigned int uCurrentMsgIndex;
    }; 
    static void GetServerList(string instruct, vector<STRU_GAME_SERVER>& servlist);

    static void GetCharList(string instruct, vector<string>& charlist);int DispatchID();
      

  9.   

    这个代码似曾相识啊  InitializeCriticalSection(&g_sect); //这个应该先初始化
     
    hthread1=CreateThread(NULL,0,ThreadProc1,NULL,0,&IDThread1);
      hthread2=CreateThread(NULL,0,ThreadProc2,NULL,0,&IDThread2);
      CloseHandle(hthread1);
      CloseHandle(hthread2);