我正在尝试查找给定主机中的端口是打开还是关闭。我不知道这是否是正确的方法。在这里,我只检查0到1024之间的端口。有人可以说这是否正确,因为我的大多数端口都是关闭的,而有些端口只是打开的,还有什么方法可以打印端口名称,例如端口号是80时,端口名称是HTTP。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<error.h>
#include<errno.h>
char *convert_int_to_string(int num)
{
int tmp;
int i = 0;
int j = 0;
static char a[5] = {'0'};
while (num > 0) {
tmp = num % 10;
a[i++] = tmp + '0';
num = num / 10;
}
a[i] = '\0';
for (j = 0; j < i / 2; j++) {
tmp = a[j];
a[j] = a[i - j - 1];
a[i - j - 1] = tmp;
}
return a;
}
int main(int argc, char **argv)
{
int status;
char *node;
char *port_no;
int sock_fd;
int i = 0;
struct addrinfo hints, *serviceinfo;
if (argc != 2)
error(1, errno, "Too many or few arguments\n");
node = argv[1];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
for (i = 0; i < 1024; i++) {
port_no = convert_int_to_string(i);
status = getaddrinfo(node, port_no, &hints, &serviceinfo);
if (status != 0) {
error(1, errno, "error in getaddrinfo() function call\n");
}
sock_fd = socket(serviceinfo->ai_family, serviceinfo->ai_socktype, serviceinfo->ai_protocol);
if (sock_fd == -1)
error(1, errno, "error in socket() function call\n");
status = connect(sock_fd, serviceinfo->ai_addr, serviceinfo->ai_addrlen);
if (status != -1)
printf("Port : %s is open\n", port_no);
else
printf("Port : %s is closed\n", port_no);
}
}
答案 0 :(得分:1)
如果您只想检查TCP端口而不是UDP,我建议您简单地尝试将connect()连接到服务器并等待一段时间,然后再假设该端口已关闭。
您必须使用poll()或select()才能使connect()调用超时。 (C: socket connection timeout)
这是一个可行的示例: (仅适用于IP,不适用于域名,因此您必须ping服务器以查找其IP地址或自己实现dns查询)
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#define MAX_PORT 1024
#define TIMEOUT 5000
int main(int argc, char *argv[])
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = inet_addr(argv[1])
};
struct pollfd fds[1];
for (uint16_t port = 0; port < MAX_PORT; port++) {
int8_t sock = socket(PF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);
fds[0].fd = sock;
fds[0].events = POLLOUT;
addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (errno == EINPROGRESS) {
if (poll(fds, 1, TIMEOUT) > 0)
printf("Port %d opened.\n", port);
else
printf("Port %d closed.\n", port);
}
else
printf("Port %d closed.\n", port);
}
else
printf("Port %d opened.\n", port);
close(sock);
}
}