开发者

socket connect timeout in c using poll

开发者 https://www.devze.com 2023-04-06 11:57 出处:网络
I have an existing multi-threaded application which uses blocking connect() call. However, I want to introduce connect timeout for application where if server does not respond to our query in x mill

I have an existing multi-threaded application which uses blocking connect() call.

However, I want to introduce connect timeout for application where if server does not respond to our query in x milliseconds, application will stop trying and give error.

However, I am not able to figure out how to do that using poll.

@caf 's non blocking 开发者_如何学JAVAconnect using select has been of great help. But I have read that select in slow compared to poll, hence I want to use poll. Could you please tell me if that is true?

I am pasting his code from the post here

int main(int argc, char **argv) {
u_short port;                /* user specified port number */
char *addr;                  /* will be a pointer to the address */
struct sockaddr_in address;  /* the libc network address data structure */
short int sock = -1;         /* file descriptor for the network socket */
fd_set fdset;
struct timeval tv;

if (argc != 3) {
    fprintf(stderr, "Usage %s <port_num> <address>\n", argv[0]);
    return EXIT_FAILURE;
}

port = atoi(argv[1]);
addr = argv[2];

address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(addr); /* assign the address */
address.sin_port = htons(port);            /* translate int2port num */

sock = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);

connect(sock, (struct sockaddr *)&address, sizeof(address));

FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 10;             /* 10 second timeout */
tv.tv_usec = 0;

if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
{
    int so_error;
    socklen_t len = sizeof so_error;

    getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);

    if (so_error == 0) {
        printf("%s:%d is open\n", addr, port);
    }
}

close(sock);
return 0;

}

Could you please help me to write similar functionality using poll.

I am on RHEL and using gcc 4.5.x version.

Update: For current code, how can change socket to blocking mode once app creates connections to server. I am not able to find a way to unset this O_NONBLOCK. Update 2: fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) & ~O_NONBLOCK); One post has pointed that we can do this with above command. Didn't get the login though.


The performance of select() and poll() relative to other system-dependent polling APIs is equivalent if there are only a few file descriptors that are being polled. They both scale poorly, but can perform just fine when the program is only listening to a few fds.

An advantage of other system-specific polling APIs tends to be that they push associated state into the kernel so that each polling syscall does not require a copy of state from userspace to kernelspace. With only a few events, this copy and scan overhead is insignificant, and this benefit does not exist.

Just stick with select() unless you need to scale to handling hundreds or more fds.

If you really will be handling many fds, and you must support both Linux and Solaris, consider using a library like libevent or libev to abstract away the kernel-specific efficient wait APIs.


select won't be slower than poll. But even if it were, it's unlikely that the minimal difference would matter in your application.

For doing a nonblocking timeout connect you can copy from existing applications that provide such functionality. (see for example here, for an idea on how to do it).

0

精彩评论

暂无评论...
验证码 换一张
取 消