Discussion:
Sockets: recv=-1 BUT WSAGetLastError=0 (??)
(too old to reply)
Ricardo Vazquez
2007-03-01 12:27:26 UTC
Permalink
Hi everyone!

Something weird is happening with an application of mine:
It works OK on any computer but on one (I have nearly one hundred
installations made, up and running).
The computer on which it is not running is: WinXP professional 2002 SP2 on
AMD Athlon64

Mainly my app is a TCP server.
Each client has a listening thread with a loop and a call to the platform
SDK Windows sockets blocking (synchronous) "recv" function
(http://msdn2.microsoft.com/en-us/library/ms740121.aspx) -code below.

According to MS documentation when function "recv" returns SOCKET_ERROR
(-1), an error can be therefore retrieved with WSAGetLastError.
As you can see, I check WSAGetLastError immediately after returning recv.
This works perfectly in every computer.
But on this very one computer out of 100, several times a day, "recv"
returns SOCKET_ERROR (-1), BUT WSAGetLastError returns 0 (!!!)
Sniffing the TCP traffic via Ethereal software I can see that, in fact, the
TCP connection is still up: so it is the "recv" function that is telling me
a lie.

Has this happened to anyone out there?
Have you find any Windows or Athlon64 known bug regarding this matter
(recv=-1 but WSAGetLastError=0)?
Can you think of a way to make my application work on this problematic
computer?

Thank you very much!

Ricardo Vázquez.
Madrid, Spain.


--------------- CODE ---------------
int CClientThread::Run()
{
char msg[maxLen];

while (!bExit) {
int nRet = recv(clientSocket, msg, maxLen, 0);
if (nRet == SOCKET_ERROR && bExit) {
// Stop closes clientSocket on exit. WSAETIMEDOUT
err.Format("Stop closes clientSocket on exit");
g_logSystem.logWarning(0, err);
break;
}
else if (nRet == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
if (nErr == 0)
{
err.Format("recv=-1 but WSAGetLastError=0 from client %s on socket
%ld.", clientId, clientSocket);
g_logSystem.logWarning(0, err);
continue;
}
else
{
err.Format("Connection lost with client %s on socket %ld. Error code
%ld: recv() = SOCKET_ERROR", clientId, clientSocket, nErr);
g_logSystem.logWarning(0, err);

closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return SOCKET_ERROR;
}
}
else if (!nRet) {
// Connection has been gracefully closed.
err.Format("Client %s with socket %ld has closed the connection: recv() =
0 (apparently)", clientId, clientSocket);
g_logSystem.logNormal(0, err);

closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return 0;
}
else {
// Proccess message:
msg[nRet] = 0x0;
err.Format("[Cli %ld] Received: %s", clientSocket, msg);
g_logSystem.logNormal(4, err);

CString sMensaje;
sMensaje = CStrTok(msg, "%");
while (!sMensaje.IsEmpty())
{
parse(sMensaje);
sMensaje = CStrTok("", "%");
}
}
}
return 0;
}
Michael K. O'Neill
2007-03-02 17:31:02 UTC
Permalink
Since there's been no response in any of the groups you selected, you might
try asking this question in alt.winsock.programming
Post by Ricardo Vazquez
Hi everyone!
It works OK on any computer but on one (I have nearly one hundred
installations made, up and running).
The computer on which it is not running is: WinXP professional 2002 SP2 on
AMD Athlon64
Mainly my app is a TCP server.
Each client has a listening thread with a loop and a call to the platform
SDK Windows sockets blocking (synchronous) "recv" function
(http://msdn2.microsoft.com/en-us/library/ms740121.aspx) -code below.
According to MS documentation when function "recv" returns SOCKET_ERROR
(-1), an error can be therefore retrieved with WSAGetLastError.
As you can see, I check WSAGetLastError immediately after returning recv.
This works perfectly in every computer.
But on this very one computer out of 100, several times a day, "recv"
returns SOCKET_ERROR (-1), BUT WSAGetLastError returns 0 (!!!)
Sniffing the TCP traffic via Ethereal software I can see that, in fact, the
TCP connection is still up: so it is the "recv" function that is telling me
a lie.
Has this happened to anyone out there?
Have you find any Windows or Athlon64 known bug regarding this matter
(recv=-1 but WSAGetLastError=0)?
Can you think of a way to make my application work on this problematic
computer?
Thank you very much!
Ricardo Vázquez.
Madrid, Spain.
--------------- CODE ---------------
int CClientThread::Run()
{
char msg[maxLen];
while (!bExit) {
int nRet = recv(clientSocket, msg, maxLen, 0);
if (nRet == SOCKET_ERROR && bExit) {
// Stop closes clientSocket on exit. WSAETIMEDOUT
err.Format("Stop closes clientSocket on exit");
g_logSystem.logWarning(0, err);
break;
}
else if (nRet == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
if (nErr == 0)
{
err.Format("recv=-1 but WSAGetLastError=0 from client %s on socket
%ld.", clientId, clientSocket);
g_logSystem.logWarning(0, err);
continue;
}
else
{
err.Format("Connection lost with client %s on socket %ld. Error code
%ld: recv() = SOCKET_ERROR", clientId, clientSocket, nErr);
g_logSystem.logWarning(0, err);
closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return SOCKET_ERROR;
}
}
else if (!nRet) {
// Connection has been gracefully closed.
err.Format("Client %s with socket %ld has closed the connection: recv() =
0 (apparently)", clientId, clientSocket);
g_logSystem.logNormal(0, err);
closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return 0;
}
else {
msg[nRet] = 0x0;
err.Format("[Cli %ld] Received: %s", clientSocket, msg);
g_logSystem.logNormal(4, err);
CString sMensaje;
sMensaje = CStrTok(msg, "%");
while (!sMensaje.IsEmpty())
{
parse(sMensaje);
sMensaje = CStrTok("", "%");
}
}
}
return 0;
}
Arkady Frenkel
2007-03-05 07:26:37 UTC
Permalink
Are you sure you call GetLastError() exactly after you check return code of
recv() ? Just a hint
Arkady
Post by Ricardo Vazquez
Hi everyone!
It works OK on any computer but on one (I have nearly one hundred
installations made, up and running).
The computer on which it is not running is: WinXP professional 2002 SP2 on
AMD Athlon64
Mainly my app is a TCP server.
Each client has a listening thread with a loop and a call to the platform
SDK Windows sockets blocking (synchronous) "recv" function
(http://msdn2.microsoft.com/en-us/library/ms740121.aspx) -code below.
According to MS documentation when function "recv" returns SOCKET_ERROR
(-1), an error can be therefore retrieved with WSAGetLastError.
As you can see, I check WSAGetLastError immediately after returning recv.
This works perfectly in every computer.
But on this very one computer out of 100, several times a day, "recv"
returns SOCKET_ERROR (-1), BUT WSAGetLastError returns 0 (!!!)
Sniffing the TCP traffic via Ethereal software I can see that, in fact,
the TCP connection is still up: so it is the "recv" function that is
telling me a lie.
Has this happened to anyone out there?
Have you find any Windows or Athlon64 known bug regarding this matter
(recv=-1 but WSAGetLastError=0)?
Can you think of a way to make my application work on this problematic
computer?
Thank you very much!
Ricardo Vázquez.
Madrid, Spain.
--------------- CODE ---------------
int CClientThread::Run()
{
char msg[maxLen];
while (!bExit) {
int nRet = recv(clientSocket, msg, maxLen, 0);
if (nRet == SOCKET_ERROR && bExit) {
// Stop closes clientSocket on exit. WSAETIMEDOUT
err.Format("Stop closes clientSocket on exit");
g_logSystem.logWarning(0, err);
break;
}
else if (nRet == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
if (nErr == 0)
{
err.Format("recv=-1 but WSAGetLastError=0 from client %s on socket
%ld.", clientId, clientSocket);
g_logSystem.logWarning(0, err);
continue;
}
else
{
err.Format("Connection lost with client %s on socket %ld. Error code
%ld: recv() = SOCKET_ERROR", clientId, clientSocket, nErr);
g_logSystem.logWarning(0, err);
closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return SOCKET_ERROR;
}
}
else if (!nRet) {
// Connection has been gracefully closed.
err.Format("Client %s with socket %ld has closed the connection: recv()
= 0 (apparently)", clientId, clientSocket);
g_logSystem.logNormal(0, err);
closesocket(clientSocket);
server->DeleteClient(clientSocket);
cti_RemoveEventListener(this);
return 0;
}
else {
msg[nRet] = 0x0;
err.Format("[Cli %ld] Received: %s", clientSocket, msg);
g_logSystem.logNormal(4, err);
CString sMensaje;
sMensaje = CStrTok(msg, "%");
while (!sMensaje.IsEmpty())
{
parse(sMensaje);
sMensaje = CStrTok("", "%");
}
}
}
return 0;
}
Loading...