How to check if remote UDP port is open? C [duplicate]

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

This question already has an answer here:

It's easy to test for TCP, but how about UDP? Here: Check if OpenVPN UDP Port is open I read that it is impossible to do this. However, here: How to retrieve both TCP and UDP ports with Nmap? it was proved that nmap can do this, so its possible I think.

I wrote a very simple code:

#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; } 

But it prints nothing, just ends. So its hard to say what happend, if the port is opened or not. Is there a simple way, using sockets, to test whether the remote UDP port is opened?

回答1:

It's easy to test for TCP [ports being open], but how about UDP?

It's not possible to reliably detect that a remote port of either flavor is closed. It is not even possible to reliably detect that a remote TCP port is open -- the best you can do is determine whether that port is open to you, by successfully connecting to it. The remote machine may affirmatively reject your connection attempt even though it would accept connections from a different machine, and it may silently ignore the attempt whether the port is open (to other machines) or closed.

All of that applies to UDP as well, except that you cannot rely on a response from the remote machine even if it accepts your packet. You may get an affirmative rejection, but if you don't, you learn nothing from the attempt. You can scan for a particular UDP service running and serving request from your machine on the remote port, but you can't count more generally on being able to determine whether the port is open.



回答2:

Your socket is created with SOC_STREAM, but never connected. In such situation sendto fails with ENOTCONN. The code prints nothing because close(sockfd) succeeds and resets errno to 0.

Notice also that you don't need to test errno; it is guaranteed to be non-zero once sendto fails:

    if ((send_size = ....) < 0) {         perror("send");         close(sockfd);         ....     } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!