CraigWardman.com

[ C++ Port Scanner using Winsock with Timeout ]

/Blog/Post

A catalogue of my discoveries in software development and related subjects, that I think might be of use or interest to everyone else, or to me when I forget what I did!

C++ Port Scanner using Winsock with Timeout

Saturday, 30 July 2005


When writing the UltraChat program, I needed to write a port scanner that would look for running UltraChat servers.

A port scanner basically attempts to connect to a host on a given port and return true or false if a connection was (or wasn't) established. The problem with doing this is that when a connection cannot be establish, Winsock (windows sockets) will keep trying, allowing for servers that are slow to reply. Which then slows the whole process down.

To get around this I used a simple threading and timer technique to kill the request if it doesnt succeed within a given time.

Code:


bool quickConnect(char* remoteHostIP, int port)
{
struct sockaddr_in sAddress;

//set up connection info
sAddress.sin_family = AF_INET;
sAddress.sin_port = htons(port); //port
sAddress.sin_addr.S_un.S_addr = inet_addr(remoteHostIP); //IP

//use a thread to do the connection
HANDLE tConnThread;
DWORD threadID;
DWORD tExitCode=0;

tConnThread=CreateThread(NULL,0,&quickConnectTTL,&sAddress,0,&threadID);

//now wait 1seconds maximum for response
SYSTEMTIME now;
GetSystemTime(&now);

int finishTime=(now.wDay * 24 * 60)+(now.wHour * 60)+(now.wSecond)+1;
int nowTime=0;

while(nowTime<finishTime){
GetSystemTime(&now);
nowTime=(now.wDay * 24 * 60)+(now.wHour * 60)+(now.wSecond);
//check if already exited, dont waste time
GetExitCodeThread(tConnThread,&tExitCode);
if(tExitCode!=STILL_ACTIVE){
break;
}
}

//get the return value from connection
GetExitCodeThread(tConnThread,&tExitCode);

//if thread did not exit, time is up, close the thread and assume no server
if(tExitCode==STILL_ACTIVE){
TerminateThread(tConnThread,0);
tExitCode=0;
}

CloseHandle(tConnThread);

bool present;
//check return values
if(tExitCode==1){
present=true;
}
else{
present=false;
}

return present;

}

DWORD WINAPI quickConnectTTL(LPVOID sAddressPTR){
//copy struct info from PTR
struct sockaddr_in sAddress;
memcpy(&sAddress,sAddressPTR,sizeof(struct sockaddr_in));

//connect to remote host
int concode;
SOCKET s=socket(AF_INET,SOCK_STREAM,0);
concode=connect(s ,(struct sockaddr *)&sAddress,sizeof(sAddress));

if(concode==SOCKET_ERROR){
ExitThread(0);
return 0;
}
else{
closesocket(s);
ExitThread(1);
return 1;
}
}


The above example waits 1 second for a reply, and then assumes a false result. To use the code, you need to include the windows sockets headers and initialise the winsock, then call quickConnect passing the host/port.

Labels:

Share This!



0 Comments:

Post a Comment

<< Home

CraigWardman.com