My experiment showed that I can write to a non-blocking socket just after the connect()
call, with no TCP connection established yet, and the written data correctly received by the peer after connection occured (asynchronously). Is this guaranteed on Linux / FreeBSD? I mean, will write()
return > 0 when the connection is still in progress? Or maybe I was lucky and the TCP connection was successfully established between the connect()
and write()
calls?
The experiment code:
int fd = socket (PF_INET, SOCK_STREAM, 0);
fcntl(fd, F_SETFL, O_NONBLOCK)
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(_ip_port.port);
addr.sin_addr.s_addr = htonl(_ip_port.ipv4);
int res = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
// HERE: res == -1, errno == 115 (EINPROGRESS)
int r = ::write(fd, "TEST", 4);
// HERE: r == 4
P.S.
I process multiple listening and connecting sockets (incoming and outgoing connections) in single thread and manage them by epoll. Usually, when I want to create a new outgoing connection, I call non-blocking connect()
and wait the EPOLLOUT
(epoll event) and then write()
my data. But I noticed that I can begin writing before the EPOLLOUT
and get appropriate result. Can I trust this approach or should I use my old fashion approach?
P.P.S.
I repeated my experiment with a remote host with latency 170ms and got different results: the write()
(just after connect()
) returned -1 with errno == EAGAIN
. So, yes, my first experiment was not fair (connecting to fast localhost), but still I think the "write()
just next to connect()
" can be used: if write()
returned -1 and EAGAIN, I wait the EPOLLOUT
and retry writing. But I agree, this is dirty and useless approach.
poll()
. It is merely correct. Correctness is not a function of time. – user207421