send returns an unknown error (winsock) ?

Started by
7 comments, last by Ysaneya 21 years, 9 months ago
Greets all, I have a pretty weird error in my application. It''s a pretty standard client/server model based on TCP/IP with Winsock. The send function returns an unknown error 183 (while all winsock errors are above 10000). It happens when the other side is doing some CPU intensive or I/O intensive operations, like loading a file from the disk for many seconds. The sockets are asynchronous but networking is (not yet) threaded. I''m suspecting an internal buffer overflow, but still can''t figure out why the send function is not returning any correct error code. Any idea ? Y.
Advertisement
That''s odd because 183 is ''Cannot create a file when that file already exists.''
Martin Piper
How are you performing the async I/O? Are you using non-blocking sockets, completion routines, WSAGetOverlappedResult, Windows messaging, I/O completion ports etc?



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Basically i do not use any Win-specific stuff, since the code has to be portable to Irix. That means WSA calls limited to the minimum and no windows messaging. I use select to check for the I/O status and unblock the sockets with ioctlsocket.

I have found that the error 183 was generated by a previous piece of code, that has nothing to do with networking. Yet, the send call returns SOCKET_ERROR. Then i call WSAGetLastError as specified and get that error 183. It''s as if the send was not generating any error, but returning SOCKET_ERROR anyway.

Y.
You are sure you have a valid file handle?
Can you post the code you're using to select and send on the socket? That might help...

You say that you get an errno value 183 in a different part of the code, then when you get SOCKET_ERROR, WSAGetLastError returns the same error code? What call is it that originally returns the 183 error?

Also, when do you set your socket to non-blocking? It could be that your non-blocking connect() is still in progress when you get to the send() call.

Editted because I apparently can't read today...

[edited by - fingh on July 16, 2002 6:05:25 PM]

[edited by - fingh on July 16, 2002 6:07:47 PM]
Well, technically if a piece of code used a Win32 function that internally called SetLastError() after an error then it is possible that if send() didn''t generate an error that GetLastError() would return the last error, which would actually be from the previous code.

Now why send() would be returning a SOCKET_ERROR is strange.

Weird. Without seeing some code I can only guess at the problem

Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Yes, the file handle is valid because it doesn''t fail the first time i call send, but after a few seconds (as i said, i''m suspecting a buffer overflow while the other side is busy loading some data). The code that''s generating the 183 error has nothing to do with networking, and perfectly normal in the context (caused by CreateFile).

Now to answer your questions: i set the socket as non-blocking just after the connect call, but as i previously said, it''s not failing the first time i call send, but many many times later.

Here''s the code i use to select:


  /// Updates the socket status over the networkvoid VRTCPIP::idle(){    VR_ENTER(VRTCPIP::idle);    resetEvents();    struct timeval stv;    stv.tv_sec=0;    stv.tv_usec=0;    if (select(0,&pInputSet,&pOutputSet,&pExcSet,&stv)<0)        displayError();    VR_LEAVE;}  


Now the send call returning SOCKET_ERROR:


  /// Writes some data to this socketint VRSocket::write(    char                *buffer,            // source data    int                 size                // number of bytes to write    ){    VR_ENTER(VRSocket::write);    if (pSocket==0 || pClosed)        return(0);    if (size==0)        return(0);    int res=send(pSocket,buffer,size,0);    if (res==SOCKERR || size!=res)    {		VRLog::print("A TCP/IP Error has occured, connection is about to close:");		VRTCPIP::displayError();		for (int i = 0; i < 20; i++)		{			Sleep(5);			res = send(pSocket, buffer, size, 0);			if (res != SOCKERR && size == res)				break;		}		if (i >= 20)		{	        pClosed=true;		    return(0);		}    }    VRTCPIP::pSent+=res;    return(res);    VR_LEAVE;}  


And SOCKERR is a macro defined as INVALID_SOCKET in the header files.

Y.
when using non-blocking sockets you will get errors on send() if the TCP stack has enough data so the buffer is full. instead of waiting it returns with an error. i forget which error code is used (check the docs), but its possible that the code is wierd due to that. possibly the other side is quiting or not calling recv() enough so the connection hangs. just becuase you use select dont mean it can handle the amount of data you request when you call send(). its normal in a non blocking situtaion for res!=size and you have to handle that, not just quit. i am sure you handle this on recv (ie recv returns less then you request is perfectly normal).

does the connection die totally if you dont have the apps exit?
This is also my theory, but i still don''t get why i have an error without being able to call WSAGetLastError !? And if the buffer is full (since the other side is busy for many seconds), shouldn''t send return an amount of sent bytes of 0, instead of an error ? ( Or, at least, return a valid error! ).

How am i supposed to handle that problem ? I mean, i can''t continue the execution, since the sent message might be important. But if i loop until the message is sent, it might pause the server for many seconds (until the client is ready). Using threads would result in the same problem but at a different level, because i''d use a synchronized message queue for each connection, but the queued messages would be in a limited number too.. or i could make these client-related operations in a thread, but i''d prefer not to rely on a specific client behavior.

Y.

This topic is closed to new replies.

Advertisement