I am trying to connect to 80 and 800 ports on 1.1.1.1
. I expect connect()
to fail on 1.1.1.1:800
, but instead it blocks my program completely.
I tried using SOCK_NONBLOCK
, but doing asynchronous operations on such a small application seems inappropriate.
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
void foo(uint16_t port) {
printf("Starting for %d...\n", port);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sockaddr_in;
sockaddr_in.sin_family = AF_INET;
sockaddr_in.sin_addr.s_addr = inet_addr("1.1.1.1");
sockaddr_in.sin_port = htons(port);
printf(
"connect: %d\n",
connect(sockfd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in))
);
printf("Errno: %d\n", errno);
close(sockfd);
}
int main() {
foo(80);
foo(800);
}
Output:
Starting for 80...
connect: 0
Errno: 0
Starting for 800...
Establishing a TCP connection involves sending a message and receiving a reply.
This obviously isn't instantaneous. If you want to obtain the result of the connection attempt, you will necessarily need to wait for the result, either by blocking, or by using an asynchronous operation.
You're seem to think the first attempt to connect
didn't block, but it did. It just didn't block as long. 1.1.1.1 probably actively refused the connection to 80, producing a response in the time it takes to send a packet and receive a reply. But maybe 1.1.1.1 ignores connections to 800 or redirects them to an offline machine, leaving the client without a response until it times out.
There are ways of shortening the timeout here, including some very simple ones.