75592

Write to the client returns EWOULDBLOCK when server is slow

I am trying to write some data in the socket after specific time interval. I have two threads, one thread maintaining the TCP connection, and another thread generating data.

The data generating therad generates data, and writes it to a shared memory. The server threadreads data from the shared memory, and sends it to the client.

But, when the data generating thread becomes slow, when a lot of calculations involved, the server thread gets a EWOULDBLOCK error when trying to write to the client. But, surprisingly, from the client side, there is no such error.

If I am not wrong, EWOULDBLOCK error is returned when server is faster than client and the socket buffer is not completely read before it gets written again. But, here the case is totally opposite.

Can it be because the server therad is kept on sleep till the data generation thread completes( data thread has a higher priority).

Can somebody explain what might be happening here?

Answer1:

EWOULDBLOCK is returned when you are using a non-blocking socket and there is not enough space in the kernel's outgoing-data-buffer for that socket to hold any of the data you want to send. That could happen if the client is reading too slowly, but it could also happen (even with a fast client) if the server tries to send a large amount of data at once; for example, if your calculation thread spend a long time calculating data, and then at the end of the calculation suddenly passed over 300,000 bytes of data at once, your server thread might do something like this:

<ol> <li>See that some data is available in the shared-memory area, time to start sending it!</li> <li>Call send() with len=300000. send() absorbs as much of that data as it can fit into the kernel's outgoing-socket-data-buffer (e.g. 131,072 bytes) and returns 131072 to indicate what it has done.</li> <li>Now your server thread sees that it still has 168928 bytes of data left to send, so it calls send() again with len=168928. At this point, the kernel's outgoing-socket-data-buffer is still completely full (because there has been no chance to send any packets yet), so send() returns EWOULDBLOCK.</li> </ol>

In general, as long as you are using non-blocking sockets, EWOULDBLOCK is something your code will need to handle. The way I usually handle it is:

<ol> <li>Wait inside select() (or poll() or etc) until the socket returns ready-for-write</li> <li>When the select()/poll() indicates that the socket is ready-for-write, call send() on the socket until you've sent all the available data, OR until send() returned EWOULDBLOCK (whichever comes first).</li> <li>If you got EWOULDBLOCK in step 2, goto 1.</li> </ol>

That way your send-thread will always feed the outgoing data to the kernel as fast as possible, but no faster -- i.e. you don't waste any CPU do busy-looping, but you also don't waste time by inserting any unnecessary delays into the process.

Recommend

  • How can I have a multi-line item in a ListControl MFC?
  • Relationship between vectors and matrices in R? [closed]
  • Calling a JS function from HTML IFRAME (both web resources)
  • Getters and Setters in Eclipse for Hungarian Style Members
  • Azure deployment continually recycling since upgrading the June 2012 SDK 1.7
  • C++ String tokenisation from 3D .obj files
  • Determining the length of a read stream in node js
  • css font-size and line-height not matching the baseline
  • How to replace TouchesBegan with UIGestureRecognizer
  • Save website uploads in a subdomain
  • incomplete type 'struct' error in C
  • What's the name of this finding square root algorithm?
  • JSR-330 support in Picocontainer : @Inject … @Named(\"xxx)
  • Cast between interfaces whose interface signatures are same
  • Ember.js model to be organised as a tree structure
  • Using a canvas object in a thread to do simple animations - Java
  • Reduction and collapse clauses in OMP have some confusing points
  • How can I speed up CURL tasks?
  • Insert new calendar with SyncAdapter- Calendar API Android
  • Ensure fsync did its job
  • Jackson Parser: ignore deserializing for type mismatch
  • OpenGL ES texture problem, 4 duplicate columns and horizontal lines (Android)
  • QLineEdit password safety
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • TFS: Get latest causes slow project reloading
  • ActionScript 2 vs ActionScript 3 performance
  • How to make Safari send if-modified-since header?
  • How can I estimate amount of memory left with calling System.gc()?
  • How to pass list parameters for each object using Spring MVC?
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • SQL merge duplicate rows and join values that are different
  • Hits per day in Google Big Query
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • LevelDB C iterator
  • Linking SubReports Without LinkChild/LinkMaster
  • Can't mass-assign protected attributes when import data from csv file
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • JaxB to read class hierarchy
  • How can i traverse a binary tree from right to left in java?