我正在编写一个“hello world”客户端应用程序,它具有非阻塞connect
函数调用。我有一个echo服务器,它在同一主机上监听3000端口,我希望实现10秒超时的连接机制。我已将client_f
d套接字设置为非阻塞模式。在connect
执行函数之后,我调用select with needed timeout,但下一行代码(printf("Writing it immediately after select\n");
)立即执行。
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
int main(void)
{
int error;
socklen_t len;
fd_set rset, wset;
// Creating socket
int client_fd = socket(AF_INET, SOCK_STREAM, 0);
if (client_fd < 0)
{
perror("[Socket creating] ");
return -1;
}
// Setting socket in non-blocking mode
int flags;
flags = fcntl(client_fd, F_GETFL, 0);
if (fcntl(client_fd, F_SETFL, flags | O_NONBLOCK) < 0)
{
perror("[Setting socket flags]");
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(3000);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int n;
n = connect(client_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
if (n < 0)
{
if (errno != EINPROGRESS)
{
return -1;
}
else
{
printf("Connection in progress!\n");
FD_ZERO(&rset);
FD_SET(client_fd, &rset);
struct timeval tval;
tval.tv_sec = 10;
tval.tv_usec = 0;
int ret = select(client_fd + 1, &rset, NULL, NULL, &tval);
printf("Writing it immediately after select\n");
printf("ret: %d\n", ret);
perror("[select error]");
}
}
else if (n == 0)
{
printf("Connection has been completed!\n");
}
else
{
printf("Waiting connection!\n");
}
close(client_fd);
return 0;
}
当echo服务器未运行且我运行客户端时,我遇到以下情况:
$ ./client
Connection in progress!
Writing it immidiatetly after select!
ret: 1
[select error]: Operation now in progress
我在这里做错了什么?这是一种通过一些超时实现非阻塞连接的正确方法吗?