ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm curious if anything can be done to speed up the error return of the connect() library call when attempting to connect to a remote server with an unopened port. When I attempt to connect to an unopened port on the localhost, the error return is practically immediate.
Here's some test code I am using:
Code:
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int FillAddress(const char* servAddr, const unsigned short servPort, struct sockaddr_in* addr);
int main(int argc, char** argv)
{
const char* servAddr = (argc > 1 ? argv[1] : "localhost");
const unsigned short servPort = (argc > 2 ? atoi(argv[2]) : 9000);
int sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd <= 0) return 1;
struct sockaddr_in addr;
if (FillAddress(servAddr, servPort, &addr) < 0) return 2;
// This connect() blocks for a very, very long time... which is
// not desirable.
int status = connect(sd, (struct sockaddr*) &addr, sizeof(addr));
printf("status = %s\n", (status == 0 ? "connected" : "not connected"));
close(sd);
return 0;
}
int
FillAddress(const char* servAddr, const unsigned short servPort, struct sockaddr_in* addr)
{
struct addrinfo* host_info = 0;
if (getaddrinfo(servAddr, 0, 0, &host_info) != 0 ||
!host_info || !host_info->ai_addr || host_info->ai_family != AF_INET)
{
if (host_info) freeaddrinfo(host_info);
return -1;
}
memcpy(addr, host_info->ai_addr, sizeof(struct sockaddr_in));
addr->sin_port = htons(servPort);
freeaddrinfo(host_info);
return 0;
}
I attempted running this program with command-line args such as:
Yep, all of the above; that's how I feel. I forgot to set the port to be non-blocking. Now the connect returns immediately.
Here's the code I added to the previous posting:
Code:
...
#include <fcntl.h>
int SetNonBlocking(int sd);
...
int main(int argc, char** argv)
{
...
SetNonBlocking(sd);
...
}
int
SetNonBlocking(int sd)
{
int curflags = fcntl(sd, F_GETFL, 0);
return fcntl(sd, F_SETFL, curflags | O_NONBLOCK);
}
---------------------------
Edit:
Cr*p... apparently setting the port to non-blocking doesn't really help at all. Sure, the connect() returns immediately, but I get an EINPROGRESS error, which basically states that the connection request is pending and that I need to wait (and select/poll) for when it is done. This sort of defeats what I am trying to accomplish.
Can someone provide a clue on how to efficiently/easily scan open ports on a system? I'd hate to have to resort to building a multi-threaded application for this pet project.
Last edited by dwhitney67; 03-02-2009 at 02:18 PM.
Strangely enough, I had the same problem even when the socket was non-blocking, although it was with a bad address. The "non-blocking" connect call would block for about 30s before returning when I used an IP address that wasn't available.
Even if the server isn't blocking for accept, you should receive a connection if it's listening, the number of pending connections hasn't been exceeded, and the client is blocking. I haven't checked if writing is actually possible between the return of connect and the server's accept. For me that's undesired behavior, but it seems to be the way it works.
In general, at least one side of the connection operation must block. I normally have the server use select and have the clients connect in blocking mode, then switch the socket to non-blocking for data transfer. It can be cumbersome to have a single-threaded server with multiple clients for this very reason. Not only that, but intentionally breaking a select call isn't pretty. If all connections are independent, however, you can just design the server to use standard input and output and add it to inetd.
Kevin Barry
PS You probably don't run google.com (just noticed that part); therefore, I assume you don't have control of the server program. With the select call suggested by man connect, though, you can put it in a loop and use a timeout of { 0, 0 } (as opposed to NULL,) which will cause it to return immediately. That way you can do other things while you wait for the connection to go through.
I'm not sure if this relates to your problem or not... It's been many years since I did socket programming (in C and C++), but when I ran into the problem of very long waits for connect, I ended up basically doing a ping first to make sure the socket was valid.
I used either ICMP or UDP for this - it's been too long to remember. But it would return a status immediately, and if OK, then I would do the connect.
This was using Winsock, so it may not even work for you.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.