我正在尝试扫描任何打开的端口并保存文本文件中的端口。程序显示第一个循环(检查参数是否正确)但由于某种原因跳过整个for循环。我是c的新手,所以非常感谢任何帮助
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define HTTP_PORT 80
int main(int argc, char ** argv)
{
int sockfd=0;
int min = atoi(argv[1]);
int max = atoi(argv[2]);
struct sockaddr_in serv_addr;
struct hostent *url;
for(int i = 0; i < argc; i++)
{
printf("%d, is %s\n",i,argv[i]);
}
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
fprintf(stderr, "ERROR: Failed to open socket\n");
return 1;
}
url = gethostbyname(argv[3]); /* does not support IP6 */
if (url == NULL) {
fprintf(stderr, "ERROR: Host not found\n");
return 2;
}
printf("Scanning ports %d - %d\n", min, max);
FILE * file = fopen("/home/llp2/Desktop/Assignment/ports.txt", "w");//open log file
for (unsigned short port = min; port < max; port++)//loop through and scan all ports
{
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr, url->h_addr, url->h_length);
serv_addr.sin_port = htons(HTTP_PORT);
/* Connect to the server */
if (connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) > 0)
{
//if the port is open get information about that port and print it to the log file
char host[128];
char service[128];
getnameinfo((struct sockaddr*)&serv_addr, sizeof serv_addr, host, (sizeof host), service, sizeof service, 0);
printf("Port : %d, Service : %s, Open\n", port, service);
fprintf(file, "Port : %d, Service : %s, Open\n", port, service);
}
close(sockfd);
}
fclose(file);//Close the file
return 0;
}
答案 0 :(得分:2)
当我按如下方式运行代码时,您正在崩溃分段错误:
g++ code.cpp
./a.out 1000 2000 localhost
首先,你是在for循环的每次迭代中关闭套接字。当您尝试第二次关闭它时,您可能会得到未定义的结果:
这一行:
close(sockfd);
}
我怀疑你想在循环的每次迭代中创建一个新套接字。
此外,如果文件无法打开,fclose(文件)调用也会崩溃。
这一行:
fclose(file);//Close the file
应该是这样的:
if (file)
{
fclose(file);
file = NULL;
}
答案 1 :(得分:1)
三件事:
首先,由于在循环的每次迭代中都有单独的连接,因此需要在循环中创建套接字。因此,在调用socket
之前,将调用转移到第二个for
循环内的connect
。
其次,看一下你要连接的地方:
serv_addr.sin_port = htons(HTTP_PORT);
每次循环都连接到端口80。如果connect
失败,则循环不会打印任何内容,无论是文件还是屏幕。因此,如果端口80未打开,您将看不到任何打印内容。
更改此项以连接到要扫描的端口:
serv_addr.sin_port = htons(port);
第三,您没有检查connect
的正确返回值。成功时返回0,错误时返回-1。您正在检查返回值是否大于0.这始终为false。所以改变它来检查0:
if (connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == 0)