July 29th, 2003, 09:59 PM
non-blocking socket, telnet not filling buffer
in my server, I wish to recieve input up to newline, when the client pushes <enter>, for this I have a function copyed from a tutorial. readLine which reads up to a newline character. I swaped this for \r, but is not working corectly.
To debug after recv() I plased a WSAGetLastError and the return code 10035 "operation would block"
I researched this and apears the recv buffer is empty, so in the case of a non-blocking socket, recv does not wait for data to arive, it just returns SOCKET_ERROR and WSAGetLastError gives 10035
Im conecting with telnet to test, and its when i push a letter, so my question is, when i push a letter in telnet, is this not sent to the target machine? and if thats the case, when is the data sent? when is my recv buffer filled.
This is non-blocking socket.
July 30th, 2003, 03:35 AM
From the man page:
So it looks like setting a receive timeout on the socket would solve your problem.
[EAGAIN] The socket is marked non-blocking, and the receive
operation would block, or a receive timeout had been
set, and the timeout expired before data were
I'm not expert, but it looks to me that the recv() call doesn't even get a chance to check the buffer, and exits immediately. I expect that you'll need to loop, checking each time to see if you got your data (break), or if you timed out (continue looping). I suspect that telnet is not your problem.
Is there a reason that you're using non-blocking sockets?
July 30th, 2003, 04:31 AM
Well im gona investigate this time out you are sugesting, its quite posible
The reason for useing non-blocking sockets, my application has a Window (GUI), in which the message loop pumps messages to my window procedure or handler, so in essance setting to non blocking i've told the socket to inform my window handler of a FD_READ when data is waiting for me.
I'ts intregueing because the docs indacte to me, my window handler only recieves a FD_READ message when there is data waiting for it. It's why this seems strange. Because if there is data waiting for me, recv should return the number of bytes recieved, but is returning <= 0 values.
July 30th, 2003, 05:06 AM
I think you're supposed to just ignore the error. See http://tangentsoft.net/wskfaq/newbie.html#wouldblock
July 30th, 2003, 07:02 AM
Thank you, that solves why the error is there, now I took out the WSAGetLastError so Im not pestered with this error. And I can ignore it.
Now I notice the return from recv is 0 indicating conection closed. Before this I was testing for <=, and I was assumeing a SOCKEt_ERROR, so now I know the return is 0 not negitive.
iRet = recv(client, buffer, 25, 0);
if (iRet == 0)
MessageBox(NULL, "Conection closed?", "Debug", MB_OK);
I read fully the link you provide, so it seems the error is normal. But particular this paragraph
The FD_READ, this is where my recv is, and now after changes I made to ignore the error message, the return of recv is 0.
The next question is, how do you know when it's safe to try again? In the case of asynchronous sockets, Winsock will send you an FD_WRITE message after a failed send() call when it is safe to write; it will send you an FD_READ message after a recv() call when more data arrives on that socket
So I can not recieve any data.
July 31st, 2003, 09:28 PM
first I thank you so much for your help j3r, and it was a big help. Ive done alot of debuging and error checking and what I determined was I had a combination of problems.
One such problem was a miss understanding on my part, Asynchronous != Non-Blocking, simular but not the same, in in that sence alot of confusion has creaped into my code.
Turns out one of the problems was readLine a function I got from a tutorial, was intended for blocking sockets. As the function loops, recv() every time waiting untill data arives. In my case as you explained, returns imediatly. So the first loop around it gets the first character, by the times the second pass of the loop, recv fails because of operation would block, so this breaks the function. Would work fine on a blocking socket.
The other problem I had of returning 0 was another one of my mistakes:
When I read this, I acedentialy put in lParam instead of wParam, which most likely would have returned INVALID_SOCKET if i tested.
sAccept = accept(wParam, NULL, NULL);
Notice I used the variable wParam in place of the socket instance. Why? So that if I had more than one socket (s1 and s2) I could use the same message for both.
So in this sence, WSAAsyncSelect takes care of the polling for me. By sending my Window handle a message FD_ACCEPT, FD_READ.... So my mistakes mainly were mixing up lParam and wParam values. And the fact readLine is for blocking sockets.
A non-blocking socket sends out a call and the program execution continues. This is exactly what asynchronous sockets do. However, there is a major difference
When using non-blocking sockets, you have to continually poll the socket to see whether or not you have any actions that need to be performed.
Non-blocking sockets have the advantage in that they allow normal program execution to continue – meaning you can process data while waiting for more to come in.