我用C ++编写了一个端口扫描程序,该程序将在Windows中使用winsock正常工作,一切都按照我想要的方式进行,只是它非常缓慢,需要10分钟才能扫描三个端口,我只是想知道是否有一个提高性能的方法!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#pragma comment(lib,"WSOCK32.LIB")
int main()
{
WSADATA data;
SOCKET sock;
int err, i, startport, endport;
char ip[20];
struct sockaddr_in sock_addr;
FILE*fp1;
printf("ip: ");
scanf("\n%s", ip);
printf("start port: ");
scanf("%d", &startport);
printf("end port: ");
scanf("%d", &endport);
if ((WSAStartup(MAKEWORD(2, 0), &data) != 0))
{
printf("Error: Winsock did not init!!!\n\n");
}
else
{
for (i = startport; i < endport; i++)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
sock_addr.sin_family = PF_INET;
sock_addr.sin_port = htons(i);
sock_addr.sin_addr.s_addr = inet_addr(ip);
printf("Checking port %d\n", i);
err = connect(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr));
if (err == 0)
{
printf("Port Open!!!\n\n\a");
fp1 = fopen("ports.txt", "a+");
fprintf(fp1, "Port is open: %d\n\n", i);
closesocket(sock);
fclose(fp1);
}
else
{
printf("Port Closed!!!\n\n");
}
}
WSACleanup();
system("ports.txt");
}
}
答案 0 :(得分:1)
默认情况下,套接字在阻止模式下运行。您正在使用单个循环以串行方式连接到每个端口,等待一个连接完成后再尝试下一个连接。因此,当然性能会很慢。
对于要完成的操作,您需要并行运行多个connect调用。为此,您有3种选择:
对于您创建的每个阻塞套接字,启动工作线程以connect()
对其进行操作。然后,您可以创建多个套接字并一次运行它们的线程。使用WaitForMultipleObjects()
(或相关函数)来检测每个线程在其connect()
操作完成时何时终止。
对于少量的套接字,这是可以的,但对于大量的套接字,则不能扩展。
对于您创建的每个套接字,使用ioctlsocket(FIONBIO)
将其置于非阻塞模式。然后,您可以创建多个套接字并一次connect()
。使用select()
,WSAAsyncSelect()
或WSAEventSelect()
来检测每个connect()
操作何时完成。
使用WSASocket()
并启用WSA_FLAG_OVERLAPPED
标志来创建每个套接字。然后,您可以创建多个套接字并一次ConnectEx()
,为每个套接字指定一个单独的OVERLAPPED
结构。使用WaitForMultipleObjects()
+ GetOverlappedResult()
或I/O Completion Port来检测每个ConnectEx()
操作何时完成。