【问题标题】:Using Non Blocking socket in a port scanner在端口扫描器中使用非阻塞套接字
【发布时间】:2013-08-13 07:38:00
【问题描述】:

我编写了一个简单的端口扫描代码,通过建立套接字连接来查看主机是否可用。逻辑是检查连接,如果连接建立成功则主机可用,否则如果我们得到错误代码为WSACONNREFUSED,则主机存在。套接字连接是阻塞的,如果该IP地址上没有主机,则程序将被阻塞,直到发生超时。我在互联网上阅读了几个关于如何使用非阻塞套接字的示例,但他们使用读写来检查我们是否可以写入服务器端或从服务器端读取以建立连接。为此应该有一个要接受的服务器代码。有没有办法使用非阻塞套接字修改端口扫描器的现有代码,因为我希望本应用程序运行得更快一点,任何有价值的提示都会有用。

目前的代码如下。

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

int port[]={80,139};

int wmain()
{

  // Initialize Winsock
    WSADATA wsaData;
    int i=0,flag=0;
    char ip[20];
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
    wprintf(L"WSAStartup function failed with error: %d\n", iResult);
    return 1;
   }
    SOCKET ConnectSocket;
    sockaddr_in clientService;

// Create a SOCKET for connecting to server

    ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
    wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
    WSACleanup();
    return 1;
}

// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.

printf("\n Enter the Ip Address : ");
scanf("%s",ip);

clientService.sin_family = AF_INET;
clientService.sin_addr.S_un.S_addr = inet_addr(ip);


for(i=0;i<2;i++)
{
    clientService.sin_port = htons((unsigned short)port[i]);
    iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));

    if((iResult==0)||((iResult=WSAGetLastError())==WSAECONNREFUSED))
   {
     printf(" %d ",iResult);
     printf("\n Port Number : %d",port[i]);
     printf("\n Machine Found  ");
     flag=1;
     break;
   }
}

if(flag==0)
{
    printf("\n Machine not found ");
}

iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
    wprintf(L"closesocket function failed with  machine %d error: %ld\n",i, WSAGetLastError());
    WSACleanup();
    return 1;
}

WSACleanup();
return 0;
}

【问题讨论】:

    标签: c windows sockets


    【解决方案1】:

    在执行非阻塞connect(), 后,连接完成时套接字将变为可写。此时您应该检查套接字上的SO_LASTERROR 以查看连接是否成功完成。

    【讨论】:

    • 所以我必须运行一个循环来检查 SO_LASTERROR 是否已完成?
    • 我不清楚你是否只是让我无端重复自己的话,还是上面真的有你不明白的地方。
    • 我是这样理解的,我必须重复循环来检查 SO_LASTEROR 以查看连接是否成功。如果我错了,请纠正我。
    • 不行,你必须等到select() 告诉你套接字是可写的。我没有说任何关于循环的事情。
    • 另一个毫无意义的问题。 select() 不会“让处理器保持忙碌循环”。它等待一个事件。我不知道您从哪里获得信息或想法,但您的理解存在严重缺陷。
    猜你喜欢
    • 2017-04-18
    • 1970-01-01
    • 2010-10-31
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多