测试TCP很容易,但UDP怎么样?在这里:Check if OpenVPN UDP Port is open我读到这是不可能的。但是,在这里:How to retrieve both TCP and UDP ports with Nmap?证明了nmap可以做到这一点,所以我认为可能。
我写了一个非常简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char * ip_addr;
int port;
int sockfd;
struct sockaddr_in server_addr;
if (argc != 3)
{
fprintf(stderr,"Usage: %s IP port \n", argv[0]);
exit(1);
}
ip_addr = argv[1];
port = atoi(argv[2]);
if (port <= 0)
{
fprintf(stderr,"error: invalid port\n");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_aton(ip_addr, &server_addr.sin_addr);
char msg[] = "Just a text\n";
char buffer[255];
int recv_size, send_size;
if ((send_size = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*) &server_addr, sizeof(server_addr))) < 0)
{
close(sockfd);
if (errno != 0)
{
perror("send");
exit(1);
}
}else if(send_size == 0)
{
printf("sent\n");
}
else if (send_size > 0)
{
printf("sent\n");
}
if ((recv_size = recvfrom(sockfd, buffer, 255, 0, NULL, NULL)) == 0)
{
close(sockfd);
if (errno != 0)
{
perror("recv");
exit(1);
}
}
buffer[recv_size] = '\0';
close(sockfd);
return 0;
}
但它没有打印,只是结束。如果端口是否打开,很难说明发生了什么。是否有一种简单的方法,使用套接字来测试远程UDP端口是否打开?
答案 0 :(得分:2)
测试TCP [正在打开的端口]很容易,但UDP怎么样?
无法可靠地检测到任何一种风味的远程端口已关闭。甚至无法可靠地检测到远程TCP端口打开 - 您可以做的最好的事情是通过成功连接到来确定该端口是否已打开 它。即使远程计算机接受来自不同计算机的连接,它也可以肯定地拒绝您的连接尝试,并且它可以默默地忽略该端口是打开(到其他计算机)还是关闭的尝试。
所有这些也适用于UDP,除非你不能依赖远程机器的响应,即使它接受你的数据包。你可能得到肯定的拒绝,但如果你不这样做,你就不会从这次尝试中学到任何东西。您可以在远程端口上扫描从您的计算机上运行和提供请求的特定UDP服务,但是您无法更准确地计算端口是否已打开。
答案 1 :(得分:0)
您的套接字是使用SOC_STREAM
创建的,但从未连接过。在这种情况下sendto
失败并显示ENOTCONN
。代码不会打印,因为close(sockfd)
成功并将errno
重置为0。
另请注意,您不需要测试errno
; sendto
失败后保证不为零:
if ((send_size = ....) < 0) {
perror("send");
close(sockfd);
....
}