我有一个TCP端口扫描器,它可以扫描给定IP上的所有开放端口,并只返回开放端口和服务名称。要做到这一点,我创建一个套接字,将其设置为非阻塞模式,如果它超时,则表示端口关闭,否则打开。问题是我的select()总是超时,即使我试图扫描打开的端口。我希望有人把我的错误指向我,我的逻辑不好?Unix TCP端口扫描器
#include <stdlib.h>
#include <iostream>
#include <cstdio>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/time.h>
#include <errno.h>
using namespace std;
fd_set working_set;
hostent *he;
char* protoc [2] = { "tcp","udpn" };
int port;
struct sockaddr_in servaddr;
int sendfd;
servent *srvport;
void set_nonblock(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}
void set_block(int socket) {
int flags;
flags = fcntl(socket,F_GETFL,0);
assert(flags != -1);
fcntl(socket, F_SETFL, flags | ~O_NONBLOCK);
}
int main(int argc, char* argv[])
{
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
char* host = argv[1];
char* pro = argv[2];
int portlow = atoi(argv[3]);
int porthigh = atoi(argv[4]);
fprintf(stderr, "n Scanning host=%s, protocol=%s, ports: %d -> %d \n",
host, pro, portlow, porthigh);
if(strcmp(pro, protoc[0])==0)
pro = protoc[0];
else if (strcmp(pro, protoc[1])==0)
pro = protoc[1];
else
{
herror("n specify valid protocol - tcp or udpn");
exit(-1);
}
if((he = gethostbyname(argv[1])) == NULL)
{
herror("n *** gethostbyname() failed ***n");
exit(-1);
}
/*In case TCP protocol is selected for scan, app opens streaming socket
for every port to be scanned, tries to connect to it, and if successful
it displays information about service using struct servent.
*/
if(strcmp(pro, protoc[0])==0) // tcp scan
{
for(port = portlow; port <= porthigh; port++)
{
// open stream socket
if((sendfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("*** socket(,SOCK_STREAM,) failed ***n");
exit(-1);
}
set_nonblock(sendfd);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr = *((struct in_addr *)he->h_addr);
int res = connect(sendfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
int ser;
if (res < 0) {
if (errno == EINPROGRESS) {
timeout.tv_sec = 0;
timeout.tv_usec = 10;
FD_SET(sendfd, &working_set);
if ((ser=select(sendfd+1, NULL, &working_set, NULL, &timeout)) > 0) {
srvport = getservbyport(htons(port), protoc[0]);
}
else {
fprintf(stderr, "Timeout or error() %d\n",ser);
perror("select(): ");
}
}
else {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
}
if(srvport != NULL)
printf("tport %d: %sn \n ", port, srvport->s_name);
else if (ser=0)
close(sendfd);
fflush(stdout);
}
//set_block(sendfd);
}//end of for()
}
}
我修正了这个错误,但现在我得到的所有端口的列表,就是这样,我关闭套接字也不好?另外我更新了帖子中的代码。 – Karudi