Lance's TextBox

For software developers using IPWorks, PowerShell, RSSBus, etc.


News

 Subscribe Add to Technorati Favorites

 

 

 

 


 

 

Search My Blog:

 

 

My Stats

  • Posts - 439
  • Comments - 188
  • Trackbacks - 265

Twitter












Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories


Blogs


Miscellanous


Noteworthy Stuff


Popular Posts



Winsock error 10035 means "Resource not available" or "Operation would block". Huh?

This error happens when the winsock buffer of either the client or server side become full. Huh? Ok, let me try to describe it as plainly as possible:

Here are two situations in which you might see Winsock error 10035:

  • You're trying to send a massive amount of information through the socket, so the output buffer of the system becomes full.
  • You're trying to send data through the socket to the remotehost, but the remotehost input buffer is full (because its receiving data slower than you're sending it).

When you send data - you really send it to the TCP/IP subsystem of your machine (ie winsock). The system buffers this data (in the OutBuffer) and begins sending it to the remote host as fast as it can (which of course is only as fast as the receiver can receive it). If the OutBuffer gets filled, because you are sending data faster than the system can send it - you'll get Winsock error 10035.

For IP*Works! users, you will never have to worry about this error because the components deal with them for you automatically, with the exception of IPPort an IPDaemon, the basic level TCP client and server components. These two components are the building blocks with which you can build any TCP/IP solution, they give you complete control over everything.

In order to deal with this when using IPPort or IPDaemon, just catch the Winsock 10035 error and wait for the component's ReadyToSend event to fire (this fires when the system is able to send data again). At that time, you can continue sending your data, starting with that which failed. For example (C# - if you need help with other languages let me know), the code below will loop until the length of the data to be sent is 0. If all goes normally, this loop will only be entered once and all of the data will be sent. After a while, if the input buffer fills up, the SetDataToSend inside the loop will fail with the Winsock 10035 error. The code will wait for the ReadyToSend event (the ready boolean flag), and loop. SetDataToSend will be called again, successfully.

note:  The ReadyToSend event will only fire if none of the data was able to be sent.  So the code below has been updated to only wait for the event if BytesSent equals 0.  Otherwise, if some of the data was able to be sent, the code will loop immediately and attempt to resend the remaining data.

while (length > 0) { //this means that we have some bytes to send
     try 
     {
          ready = false;
          ipport1.SetDataToSend(TextB, offset, length);
          length -= ipport1.BytesSent;
          tbStatus.AppendText(ipport1.BytesSent.ToString() + " bytes sent." + "\r\n");
     }
     catch (nsoftware.IPWorks.IPWorksException ex1) 
     {
          if (ex1.Code == 135) //WOULDBLOCK Error
          {
               if (ipport1.BytesSent == 0) 
while (!ready) { ipport1.DoEvents(); }
               length -= ipport1.BytesSent; offset += ipport1.BytesSent;
               tbStatus.AppendText("Retrying Send..." + "\r\n"); 
          }
     }
}


posted @ Wednesday, July 20, 2005 8:52 AM | Filed Under [ Programming ]

Comments

Gravatar # re: Winsock error 10035
Posted by Madhavi on 5/25/2006 12:12 AM
So if you got this error can we proceed with our work by sending the data ?when the input buffer or output bufer will get empty.
Gravatar # re: Winsock error 10035
Posted by Lance Robinson on 5/25/2006 6:26 AM
The buffer doesn't have to be empty before you can send data - it just can't be full. The system will let you know when: in the case of IP*Works!, the component will notify you by firing its ReadyToSend event. At that point you resend however many bytes didn't make it through (which will likely be all the bytes that you most recently tried to send).
Gravatar # re: Winsock error 10035
Posted by mtourangeau on 1/17/2007 12:39 PM
What about this error during recv?
Gravatar # re: Winsock error 10035
Posted by Jörg Schultz on 7/31/2007 6:34 AM
You have a solution for VB6

Thanks

Jörg
Gravatar # re: Winsock error 10035
Posted by Lance on 8/1/2007 10:37 AM
The solution for vb6 is the same. Just convert the code.
Gravatar # re: Winsock error 10035
Posted by Evgeni on 11/5/2007 10:36 AM
I have the same error when i RECEIVE data from server, on client side. I using Socket.Blocking = false. Receive buffer is big enough, I don't think that is the issue.

Server - Linux, c++
Client - Windows, C#

Thanks in advance,
Evgeni
Gravatar # re: Winsock error 10035
Posted by Bob on 1/30/2008 4:10 PM
If you are using a non-blocking socket for RX and call recv(...) and no data is available, you will get this error because the call would have to block while waiting on data - so in the RX case ignore the error.
Gravatar # re: Winsock error 10035
Posted by abcdefgh on 3/25/2008 1:07 AM
Can you tell how to overcome this problem using SENDMAIL.


Gravatar # re: Winsock error 10035
Posted by TN on 5/15/2008 2:49 PM
Hi Lance,

I copied your code above (converted to Delphi) and I get an endless loop because ipport1.BytesSent = 0 after the SetDataToSend. Is there any property I need to set for ipport to get the correct BytesSent? If I simple call SetDataToSend without any checking or loop I also get 0 BytesSent even though the data was sent correctly. Why is that?

Thank you.
Gravatar # re: Winsock error 10035
Posted by Lance on 5/15/2008 2:55 PM
TN - I cannot reproduce this here. What version are you using? Can you email me your sample code?
Gravatar # re: Winsock error 10035
Posted by TN on 5/15/2008 5:07 PM
Lance,

Thanks for the quick reply. I'm using IPWork SSL Delphi Edition version 5.0 (Build 1182) with Delphi 7. The code can be as simple as this:

procedure SendToClient(ID: integer; S: String);
var
i: integer;
begin
ipServer.DataToSend[ID] := S;
i := ipServer.BytesSent[ID];
end;

In the above example i always returns 0 even though it sent the data fine. This happens both with the IPPortS or IPDaemonS components.

Thanks.
Post a comment





 

Please add 1 and 7 and type the answer here: