Reputation: 1440
I seem to have a problem with select
.
while(!sendqueue.empty())
{
if(!atms_connection.connected)
{
//print error message
goto RECONNECT;
}
//select new
FD_ZERO(&wfds);
FD_SET(atms_connection.socket, &wfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
retval = select(atms_connection.socket + 1, NULL, &wfds, NULL, &tv);
if (retval == -1) {
printf("Select failed\n");
break;
}
else if (retval) {
printf("Sent a Message.\n");
}
else {
//printf("retval value is %d\n",retval);
printf("Server buffer is full, try again...\n");
break;
}
n = write(atms_connection.socket, sendqueue.front().c_str(), sendqueue.front().length());
}
The function belongs to a thread, which, when it acquires the lock cleans a queue using select() and writes to socket in a loop until the queue is empty.
The first time the thread gets the lock it select()
fine, but the second time it gets the lock and enters the while it always returns 0.
For the record, it used to work fine a while ago, and I haven't changed that code since then.
Upvotes: 5
Views: 10977
Reputation: 10541
Selects returns 0 when it has a timeout. The following line specifies a time out to be 1 second.
tv.tv_sec = 1;
Usually a socket is ready for write and select would return immediately. However, if there is no room in the socket output buffer for the new data, select won't flag this socket as ready for write.
For example, this condition might happen when the other side of the connection is not calling recv/read
. The amount of unconfirmed data grows and the buffer eventually becomes full. Since the timeout is fairly small, the select returns frequently with return value 0.
Upvotes: 5
Reputation: 5535
In addition to what is mentioned already, select api itself only tells whether a descriptor is ready. It can be used for both reading or writing depending upon what operation is chosen.
In your case, the "message sent" print seems to give the illusion the data is actually written, which is not the case. You have to make a write call on the descriptor which is returned as ready from select.
Select does not magically itself reads or writes to a buffer. In case you are a listening server, you call an accept or a read after select call returns successfully. In case you are a client and intend to write (like it appears in your case), you need to make an explicit write() or send() call.
Upvotes: 0