2013-08-22 22 views
1

我最终设法根据前面的thread中提供的建议编写了用于主机发现的非阻塞套接字代码。我的发现代码的逻辑是与主机建立套接字连接在80,139等端口上。如果套接字连接成功,则存在主机,或者如果主机通过发送RST数据包终止会话,则主机存在。通过使用阻塞套接字,我可以检查来自主机的RST数据包的WSACONREFUSED数据包,但即使从主机发送了用于终止会话的RST数据包,非阻塞套接字始终返回0。有没有办法在非阻塞模式下检查RST数据包? 。同样的代码如下在非阻塞套接字上检查WSACONREFUSED

#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}; //port number for scanning 

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 socketarray[2]; 

    sockaddr_in clientService; 

    // Create a SOCKET for connecting to server 

    for(i=0;i<2;i++){ 
    socketarray[i]=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    } 

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

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

    u_long iMode=1; 

for(i=0;i<2;i++) 
{ 
    ioctlsocket(socketarray[i],FIONBIO,&iMode); 
} 

    fd_set WriteFDs; 
    FD_ZERO(&WriteFDs); 
    timeval timer; 
    timer.tv_sec=5; 
    timer.tv_usec=5000000; 

for(i=0;i<2;i++) 
{   
       FD_SET(socketarray[i],&WriteFDs); 
       clientService.sin_port = htons((unsigned short)port[i]); 
       connect(socketarray[i], (SOCKADDR *) & clientService, sizeof(clientService)); 
       iResult=select(0, NULL, &WriteFDs,NULL,&timer); 

     if(iResult==SOCKET_ERROR||iResult==0) 
     { 
     printf("The return value of the function = %d",iResult); 
      wprintf(L"\n Select failed for the port number %d with error %d ",port[i], WSAGetLastError()); 

     } 
     else 
     { 
      printf("\n The return value of the function = %d",iResult); 
      wprintf(L"\n Select was success for the port number %d ",port[i]); 
     } 
} 

for(i=0;i<2;i++) 
{ 
    closesocket(socketarray[i]); 
} 


WSACleanup(); 
return 0; 
} 
+1

你真的想看看是否发送RST包吗?或者只是它断开连接?对于异步连接,当套接字可写入时,您已完成连接 - 成功或以其他方式。 – xaxxon

+0

我想通过建立连接来查找主机是否可用。 RST数据包或WSACONNREFUSED根据链接http://www.slashroot.in/what-tcp-ping-and-how-it-used指示主机的可用性。如何检查WSACONNREFUSED还是有更好的方法来检查它。 – blitz

回答

1

在进行非阻塞连接之后,您必须在套接字上选择(),直到它变为可写。然后通过setsockopt()获取最后一个套接字错误。如果没有一个,你连接。如果有,请看它是什么。

+0

该问题现已解决。谢谢你的帮助。 – blitz