All 🙂
I have some piece of code with correctly works on Linux and WinXP
int FlowTestIP::do_recvfrom()
{
int ret;
struct timeval timeout;// = {2, 0};
timeout.tv_sec = 2;
timeout.tv_usec = 0;
fd_set rfds;
while(running) {
FD_ZERO(&rfds);
FD_SET(m_socket, &rfds);
ret = select(m_socket + 1, &rfds, 0, 0, &timeout);
cout << "// select ret = " << ret << " (errno = " << errno << ")" << endl;
if (ret == -1 || ret == 0) {
if (!(ret == 0 && errno == 0))
cout << "select ret = " << ret << " (errno = " << errno << ")" << endl;
return ret;
}
if (FD_ISSET(m_socket, &rfds)) {
cout << WSAGetLastError() << endl;
break;
}
}
return recvfrom(m_socket, in_buf, mtu, 0, (struct sockaddr *)&si_other, (socklen_t *)&otherAddrSize);
}
But in Windows 7 in continues to loop even when client apptication is exited.
Bad output is
…
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
FTControlServerThread::run
FTControlServerThread::recieved
pkt->ft_tos = UCHAR_MAX
QFuture::waitForFinished()
client alive true
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
normaly (on WinXP and Linux) output will be
…
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
// select ret = 1 (errno = 0)
0
FTControlServerThread::run
FTControlServerThread::recieved
pkt->ft_tos = UCHAR_MAX
QFuture::waitForFinished()
client alive true
QFuture::finished
And that is what I am waiting from it.
Has anyone encountered with such a misbehaviour?
Thanks in advance!
P.S. As @JoachimPileborg asked to show how I call this function:
FlowTest::recv(char *payload, size_t size)
{
...
while (running) {
len = do_recvfrom(); // it virtual method of class FlowTest
if (len == -1 || len == 0) {
return len;
}
if (running && !transport_recv_helper()) {
continue;
} else {
break;
}
}
...
}
and recv is called from server GUI
void FlowTestServer::runTest(FlowTestServerHelper handler)
{
...
if ((ret = server->recv(rcvdData, (size_t *)&size)) == -1 || ret == 0 || size == 0) {
if (server_busy == 0)
break;
cout << "can't receive data (size == " << size << "; ret = " << ret << ")" << endl;
continue;
}
...
}
Firstly: Using
coutis allowed to reseterrno. It doesn’t usually, but it can, especially on first use when it has to set up the locale. You need to save the value oferrnoin a temp variable, or usefprintfand friends – as a C lib function POSIX controls its behavior.Secondly: In Windows, you need to use
WSAGetLastError()noterrno.I suggest you make a macro
sock_errnowhich will be(errno)on Linux/unix, and(WSAGetLastError())on Windows. That will enable to you to code in a platform independent manner.