Both types of send calls are nonblocking in the sense that they do not block the sending process. Also, both types will deliver the message instantly to the destination process if that process is ready to receive the message at the time of the send call. However, these types of send calls do behave differently in the case that the destination process is *not* ready to receive the message at the time of the send call: in that case, the nonblocking send call will return an error code and not deliver the message at all, while the asynchronous send call will make the kernel deliver the message later, in the background so to speak, as soon as the destination process is ready to receive it.
In practice, the non-blocking send call (that is, ipc_sendnb()) is used only when the sender already knows that the destination process is (or should be) ready to receive the message, typically because that process is blocked in an ipc_sendrec() call. The asynchronous send call (usually through asynsend()) is used when the sender needs to make sure that the destination process gets the message eventually even though that process may be doing something else at the time. So why not simply always use asynchronous send calls instead of nonblocking send calls? That's easy: the nonblocking-send call has (slightly) better performance.
I hope that helps!
Regards,
David